1 Same Tree

https://leetcode.com/problems/same-tree/

Given two binary trees, write a function to check if they are equal or not.

Two binary trees are considered equal if they are structurally identical and the nodes have the same value.

分治的思想,如果root相等,再看左右子树是否相等。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool isSameTree(TreeNode* p, TreeNode* q) {
if (p == NULL && q == NULL) {
return true;
} if (p == NULL || q == NULL) {
return false;
} if (p->val != q->val) {
return false;
} return isSameTree(p->left, q->left) && isSameTree(p->right, q->right);
}
};

2 SubTree

http://www.lintcode.com/en/problem/subtree/

You have two every large binary trees: T1, with millions of nodes, and T2, with hundreds of nodes. Create an algorithm to decide if T2 is a subtree of T1.

Example

T2 is a subtree of T1 in the following case:

       1                3
/ \ /
T1 = 2 3 T2 = 4
/
4

T2 isn't a subtree of T1 in the following case:

       1               3
/ \ \
T1 = 2 3 T2 = 4
/
4
仍然是分治的思想。如果T1当前root节点与T2的root节点相同,我们才有兴趣判断T2是否是T1的子树。如果不同,判断T2是否是T1的左子树的子树或者是T1的右子树的子树。
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param T1, T2: The roots of binary tree.
* @return: True if T2 is a subtree of T1, or false.
*/
bool isSubtree(TreeNode *T1, TreeNode *T2) {
if (T2 == NULL) {
return true;
} // //we have exhauste the root1 already
if (T1 == NULL) {
return false;
} if (T1->val == T2->val) {
if (isSameTree(T1, T2)) {
return true;
}
} return isSubtree(T1->left, T2) || isSubtree(T1->right, T2);
} private:
bool isSameTree(TreeNode *T1, TreeNode *T2) {
if (T1 == NULL && T2 == NULL) {
return true;
} if (T1 == NULL || T2 == NULL) {
return false;
} if (T1->val != T2->val) {
return false;
} return isSameTree(T1->left, T2->left) && isSameTree(T1->right, T2->right);
}
};

3 计算树的深度

int treeDepth(TreeNode *root) {
// base case
if (root == NULL) {
return 0;
} return max(treeDepth(root->left), treeDepth(root->right)) + 1;
}

4 Path Sum

https://leetcode.com/problems/path-sum/

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

For example:

Given the below binary tree and sum = 22,

              5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
bool hasPathSum(TreeNode* root, int sum) {
// base case
if (root == NULL) {
return false;
} // 当前递归层是否满足条件?
if (root->val == sum && root->left == NULL && root->right == NULL) {
return true;
} return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val);
}
};

5 Path Sum II

https://leetcode.com/problems/path-sum-ii/

Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given sum.

For example:

Given the below binary tree and sum = 22,

              5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1

return

[
[5,4,11,2],
[5,8,4,5]
]
解法1:
dfs中的sum参数记录了当前递归层需要满足的条件
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> result;
vector<int> path;
dfs(root, result, path, sum);
return result;
} private:
void dfs(TreeNode *root, vector<vector<int>> &result, vector<int> &path, int sum) {
if (root == NULL) {
return;
} path.push_back(root->val); if (root->val == sum && root->left == NULL && root->right == NULL) {
result.push_back(path);
} dfs(root->left, result, path, sum - root->val);
dfs(root->right, result, path, sum - root->val); path.pop_back();
}
};

解法2:

考虑几个问题,dfs的对象是谁?什么时候满足push到result的条件?递归基是什么?

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> result;
vector<int> path;
dfs(root, result, path, sum);
return result;
} private:
void dfs(TreeNode *root, vector<vector<int>> &result, vector<int> &path, const int &sum) { if (root == NULL) {
return;
} path.push_back(root->val); if (root->left == NULL && root->right == NULL) { int tmp = 0; for (vector<int>::const_iterator itr = path.cbegin(); itr != path.cend(); itr++) {
tmp += *itr;
} if (tmp == sum) {
result.push_back(path);
}
} dfs(root->left, result, path, sum);
dfs(root->right, result, path, sum);
path.pop_back();
}
};

6 Binary Tree Maximum Path Sum

https://leetcode.com/problems/binary-tree-maximum-path-sum/

Given a binary tree, find the maximum path sum.

The path may start and end at any node in the tree.

For example:

Given the below binary tree,

       1
/ \
2 3

Return 6.

采用分治法。要求当前tree的最大路径和,可以考虑左子树的最大路径和、右子树的最大路径和、以及包含当前结点的最大路径和三者中的最大值。

要求包含当前结点的最大路径和,需要知道左子树的单路最大路径和leftChildSingleMaxSum、右子树的单路最大路径和rightChildSingleMaxSum。其中,max( leftChildSingleMaxSum + rightChildSingleMaxSum + root->val, leftChildSingleMaxSum + root->val, rightChildSingleMaxSum  + root->val),即为包含当前结点的最大路径和。

由以上分析,不难得知,遍历每一个节点时,需要得到其单路最大路径和以及双路最大路径和。我们将其封装为returnType。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
struct returnType {
returnType(int singlePath, int doublePath)
:singlePath_(singlePath), doublePath_(doublePath)
{ } int singlePath_;
int doublePath_;
}; class Solution {
public:
int maxPathSum(TreeNode* root) {
return maxPathSumHelper(root).doublePath_;
} private:
returnType maxPathSumHelper(TreeNode *root) {
if (root == NULL) {
return returnType(0, numeric_limits<int>::min());
} // devide
returnType left = maxPathSumHelper(root->left);
returnType right = maxPathSumHelper(root->right); // conquer
int singlePath = getMax(left.singlePath_ + root->val, right.singlePath_ + root->val, root->val);
int doublePath = getMax(left.doublePath_, right.doublePath_, max(left.singlePath_ + right.singlePath_ + root->val, singlePath)); return returnType(singlePath, doublePath);
} int getMax(int x, int y, int z) {
return (x = x > y ? x : y ) > z ? x : z;
} };

7 最近公共祖先

http://www.lintcode.com/zh-cn/problem/lowest-common-ancestor/
 
最近公共祖先

给定一棵二叉树,找到两个节点的最近公共父节点(LCA)。

最近公共祖先是两个节点的公共的祖先节点且具有最大深度。

样例

对于下面这棵二叉树

  4
/ \
3 7
/ \
5 6

LCA(3, 5) = 4

LCA(5, 6) = 7

LCA(6, 7) = 7

如果两个节点都在同一棵子树中,则继续往该子树中查找。如果两个节点在不同的子树中,那么root即为最近公共祖先。

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *p, TreeNode *q) {
// p,q均在左子树中
if (covers(root->left, p) && covers(root->left, q)) {
return lowestCommonAncestor(root->left, q, p);
}
// p,q均在右子树中
if (covers(root->right, p) && covers(root->right, q)) {
return lowestCommonAncestor(root->right, q, p);
} // base case:p,q在不同的子树中,或者root即为p,q中的某一个节点
return root;
} // 辅助函数,判断节点p是否在子树中。
bool covers(TreeNode *root, TreeNode *p) {
if (root == NULL) {
return false;
} if (root == p) {
return true;
} return covers(root->left, p) || covers(root->right, p);
}
};

8 Convert Sorted Array to Binary Search Tree

Tree与其他数据结构转换这类题⽬目要求将树的结构转化成其他数据结构,例如linked list, array等,或者反之,从array等结构构成⼀棵树。

前者通常是通过树的遍历,合并局部解来得到全局解,而后者则可以利⽤分治的策略,递归将数据结构的两部分分别转换成子树,再合并。

https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/

Given an array where elements are sorted in ascending order, convert it to a height balanced BST.

/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode(int x) : val(x), left(NULL), right(NULL) {}
* };
*/
class Solution {
public:
TreeNode* sortedArrayToBST(vector<int>& nums) {
return sortedArrayToBstHelper(nums, 0, nums.size() - 1);
} private:
TreeNode* sortedArrayToBstHelper(const vector<int> &nums, int start, int end) { if (start > end) {
return NULL;
} if (start == end) {
return new TreeNode(nums[start]);
} int mid = start + ((end - start) >> 1);
TreeNode *l = sortedArrayToBstHelper(nums, start, mid - 1);
TreeNode *r = sortedArrayToBstHelper(nums, mid + 1, end); TreeNode *root = new TreeNode(nums[mid]);
root->left = l;
root->right = r;
return root;
}
};

9

 

[算法专题] Binary Tree的更多相关文章

  1. LeetCode算法题-Binary Tree Tilt(Java实现)

    这是悦乐书的第263次更新,第276篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第130题(顺位题号是563).给定二叉树,返回整棵树的倾斜度.树节点的倾斜被定义为所有 ...

  2. LeetCode算法题-Binary Tree Paths(Java实现-3种解法)

    这是悦乐书的第199次更新,第206篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第62题(顺位题号是257).给定二叉树,返回所有根到叶路径.例如: 输入: 1 / \ ...

  3. (算法)Binary Tree Max Path Sum

    题目: Given a binary tree, find the maximum path sum. For this problem, a path is defined as any seque ...

  4. LeetCode算法题-Binary Tree Level Order Traversal II(Java实现)

    这是悦乐书的第165次更新,第167篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第24题(顺位题号是107).给定二叉树,返回其节点值的自下而上级别顺序遍历(即从左到右 ...

  5. LeetCode算法题-Second Minimum Node In a Binary Tree(Java实现)

    这是悦乐书的第285次更新,第302篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第153题(顺位题号是671).给定非空的特殊二叉树,其由具有非负值的节点组成,其中该树 ...

  6. LeetCode算法题-Average of Levels in Binary Tree(Java实现)

    这是悦乐书的第277次更新,第293篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第145题(顺位题号是637).给定一个非空二叉树,以数组的形式返回每一层节点值之和的平 ...

  7. LeetCode算法题-Construct String from Binary Tree(Java实现)

    这是悦乐书的第273次更新,第288篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第141题(顺位题号是606).构造一个字符串,该字符串由二叉树中的括号和整数组成,并具 ...

  8. [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法

    二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...

  9. 一道算法题目, 二行代码, Binary Tree

    June 8, 2015 我最喜欢的一道算法题目, 二行代码. 编程序需要很强的逻辑思维, 多问几个为什么, 可不可以简化.想一想, 二行代码, 五分钟就可以搞定; 2015年网上大家热议的 Home ...

随机推荐

  1. Rabbitmq(5) 路由模式

    设置路由键 发送者 package com.aynu.bootamqp.service; import com.aynu.bootamqp.commons.utils.Amqp; import com ...

  2. 基于windows平台搭建elasticsearch

    部署准备 elasticsearch-6.0.1.zip--https://www.elastic.co/downloads/elasticsearch elasticsearch-head-mast ...

  3. html阿里云网页练习实现代码

    html <body>     <!-- 固定浮动栏 -->     <div class="guding">         <p> ...

  4. Laravel5 (cli)命令行执行脚本及定时任务

    Artisan是Laravel自带的命令行接口名称,它提供了很多有用的命令想要查看所有可用的Artisan命令,可使用list命令查看: 1 php artisan list 每个命令都可以用help ...

  5. 706. Design HashMap 实现哈希表

    [抄题]: public MyHashMap() {  主函数里面是装非final变量的,如果没有,可以一个字都不写 } [暴力解法]: 时间分析: 空间分析: [优化后]: 时间分析: 空间分析: ...

  6. python积累二:中文乱码解决方法

    根据网上提供的解决方法:添加#coding=utf-8或# -*- coding: utf-8 -*- #coding=utf-8 print "还不行?" 执行结果:还是乱码!: ...

  7. PHP+ajax实现二级联动

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. grafana add custom dashboard

    grafana-dashboard-json prometheus-operator helm 中的grafana dashboard 扩展的时候,需要转换下载(https://grafana.com ...

  9. SSD性能测试第一神器:FIO

    SSD性能测试第一神器:FIO  2017年8月12日 syswift 0 对于SSD性能测试来说,最好的工具莫过于FIO了. 上面这个可爱的小伙子名字叫Jens Axboe,他是丹麦哥本哈根大学计算 ...

  10. AI制作icon标准参考线与多面板复制

    新建10个25x25像素,色值为RGB的画板 在视图中打开显示网格 打开首选项参考线和网格,间隔和隔线都设为1 新建一个20x20像素前景色为空描边为1像素的正方形 选择对齐选项中的对齐画板,使之与画 ...