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. 201772020113 李清华《面向对象程序设计(java)》第三周学习总结

    一.测试题反思: 这次的测试题暴露出我在学习上的很多问题:首先,编程能力非常薄弱,编程题目只写出了第一个程序,还因为小问题通不过测试,以后一定要多上手练习,多阅读示例程序.其次,对理论知识的掌握不全面 ...

  2. 安装和激活Office 2019

    有条件请支持正版!相比费尽力气找一个可能不太安全的激活工具,直接买随时随地更新的Office 365确实是最好的办法.暂时没有经济实力的,可以看看这篇文章.下载OTP工具 首先到Office Tool ...

  3. 为datagrid、treegrid增加右键表头菜单,用于显示或隐藏列,注意:冻结列不在此菜单中

    var createGridHeaderContextMenu = function(e, field) { e.preventDefault(); var grid = $(this);/* gri ...

  4. python学习笔记(六)- 函数、文件json与python字典互操作

    1.函数:(方法.功能) 1.提高代码的复用性 2.让代码更简洁.简化代码 1)定义一个简单的函数 def sayHello(): #函数名,定义函数 print("hello") ...

  5. 《CSAPP》 可重定位目标文件格式

    可重定位目标文件 ELF文件 ELF头以一个16字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节顺序.ELF头剩下的部分包含帮助链接器语法分析和解释目标文件的信息.其中包括ELF头的大小 ...

  6. 丑数(python)

    题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数.   # ...

  7. python3 urllib.parse 常用函数

    1.获取url参数 urlparse from urllib import parse url = "https://docs.python.org/3.5/library/urllib.p ...

  8. 2017-2018-2 20165315 实验四《Android程序设计》实验报告

    2017-2018-2 20165315 实验四<Android程序设计>实验报告 第24章:初识Android Android Studio项目的目录树 1 build:该目录包含了自动 ...

  9. js 加减乘除失精

    js 计算失精是因为js 先将10十进制代码转化为2进制,再计算导致 具体解决方案: 1. 加 function accAdd(arg1,arg2){ var r1,r2,m; ].length}} ...

  10. Linux查看某个进程的线程

    线程是现代操作系统上进行并行执行的一个流行的编程方面的抽象概念.当一个程序内有多个线程被叉分出用以执行多个流时,这些线程就会在它们之间共享特定的资源(如,内存地址空间.打开的文件),以使叉分开销最小化 ...