[算法专题] Binary Tree
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, andT2, with hundreds of nodes. Create an algorithm to decide ifT2is a subtree ofT1.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 andsum = 22,5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1return true, as there exist a root-to-leaf path
5->4->11->2which 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 andsum = 22,5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1return
[
[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 3Return
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) =
4LCA(5, 6) =
7LCA(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的更多相关文章
- LeetCode算法题-Binary Tree Tilt(Java实现)
这是悦乐书的第263次更新,第276篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第130题(顺位题号是563).给定二叉树,返回整棵树的倾斜度.树节点的倾斜被定义为所有 ...
- LeetCode算法题-Binary Tree Paths(Java实现-3种解法)
这是悦乐书的第199次更新,第206篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第62题(顺位题号是257).给定二叉树,返回所有根到叶路径.例如: 输入: 1 / \ ...
- (算法)Binary Tree Max Path Sum
题目: Given a binary tree, find the maximum path sum. For this problem, a path is defined as any seque ...
- LeetCode算法题-Binary Tree Level Order Traversal II(Java实现)
这是悦乐书的第165次更新,第167篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第24题(顺位题号是107).给定二叉树,返回其节点值的自下而上级别顺序遍历(即从左到右 ...
- LeetCode算法题-Second Minimum Node In a Binary Tree(Java实现)
这是悦乐书的第285次更新,第302篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第153题(顺位题号是671).给定非空的特殊二叉树,其由具有非负值的节点组成,其中该树 ...
- LeetCode算法题-Average of Levels in Binary Tree(Java实现)
这是悦乐书的第277次更新,第293篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第145题(顺位题号是637).给定一个非空二叉树,以数组的形式返回每一层节点值之和的平 ...
- LeetCode算法题-Construct String from Binary Tree(Java实现)
这是悦乐书的第273次更新,第288篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第141题(顺位题号是606).构造一个字符串,该字符串由二叉树中的括号和整数组成,并具 ...
- [数据结构]——二叉树(Binary Tree)、二叉搜索树(Binary Search Tree)及其衍生算法
二叉树(Binary Tree)是最简单的树形数据结构,然而却十分精妙.其衍生出各种算法,以致于占据了数据结构的半壁江山.STL中大名顶顶的关联容器--集合(set).映射(map)便是使用二叉树实现 ...
- 一道算法题目, 二行代码, Binary Tree
June 8, 2015 我最喜欢的一道算法题目, 二行代码. 编程序需要很强的逻辑思维, 多问几个为什么, 可不可以简化.想一想, 二行代码, 五分钟就可以搞定; 2015年网上大家热议的 Home ...
随机推荐
- Django之如何预防csrf功能的方式 form提交与ajax提交
1. 什么是csrf认证: 主要是防止别人恶意登录你的账户信息用的: 2. csrf认证在django的实现方式: 分为两种, 一种是from表单提交的方式,另一种是ajax提交实现方式 前端: &l ...
- Android GreenDao 在组件化项目中的一个问题 - 2018年7月5日21:15:14
组件化项目使用GreenDao时注意的事项: 1.要在组件化中的基础库(domain层)创建实体类: 2.如果sycn之后不能生产Dao文件,使用 Android Studio 的Gradle插件重新 ...
- Hibernate 再接触 一级缓存 二级缓存 查询缓存
缓存 就是把本来应该放在硬盘里的东西放在内存里 将来存内存里读 一级缓存: session缓存 二级缓存: sessionFactory级别的 (适合经常访问,数据量有限,改动不大) 很多的se ...
- 手工搭建web项目
https://www.cnblogs.com/skyblue-li/p/5966311.html
- Windbg断点调试
[文章主题] Windbg是Windows驱动调试的重要软件,也是必须学习的软件,前面的博客介绍了一些双机调试的环境配置,只要按照我所说的步骤一步步下来就可以完成环境搭建. 本文主要介绍如何调试sys ...
- JS数组存储(两个数组相等,一个改变,另一个跟着改变)
数组是一种引用数据类型,数组引用变量只是一个引用,数组元素和数组变量在内存里是分开存放的实际的数组元素被存储在堆(heap)内存中:数组引用变量是一个引用类型的变量,被存储在栈(stack)内存中. ...
- extern和include的作用
首先要搞清楚的是.h头文件中都是一些声明性的语句,是不分配内存的,所以头文件中有对函数的声明,有define语句,有没有实例化的结构体定义,但是没有对变量的定义(比如 int a),有的只是对外变量的 ...
- python的基本用法(一)
1.什么变量,什么是数据类型? 变量就是用来存放东西的, 数据类型:字符串str,整数int,浮点数(小数)float type()函数用来检验数据格式的类型 2.什么是for循环,什么是while循 ...
- tp3.2 phpexcel 简单导出多个sheet(execl表格)
参考链接:https://blog.csdn.net/u011341352/article/details/70211962 以下是公共类PHPExcel.php文件: // 开始 <?php/ ...
- Py西游攻关之RabbitMQ、Memcache、Redis
Py西游攻关之RabbitMQ.Memcache.Redis RabbitMQ 解释RabbitMQ,就不得不提到AMQP(Advanced Message Queuing Protocol)协议 ...