您的位置:首页 > 其它

[LeetCode] 递归求解二叉树路径之和是否等于给定值(2)

2017-10-15 13:13 330 查看

[LeetCode] 递归求解二叉树路径之和是否等于给定值(2)

0.题目

leetcode : 113. Path Sum II

1.题目描述

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]
]


2.题目分析

对于如何判断二叉树的路径和是不是等于给定值在之前有一篇博客已经有了讲解:如何通过递归求解二叉树路径之和是否等于给定值。这道题是上一题的升级版本,这题不仅要我们判断路径和,所有满足条件的路径都找出来。

我们先来分析一下这两道题目在实现上有什么不同。

对于第一题来说(Path Sum I),运用“层”的思想,我们可以将问题化为在叶子节点判断叶子节点的值是否等于Sum - SumOfFathers,在遍历所有叶子节点之后我们就能判断是否存在这样的路径。

对于本题我们也可以使用这种方法来判断路径,但是我们必须要找到一种可以存储满足条件的路径的方法。

对于二叉树,有一点我们要记住从根节点往下有多条路径,但是从叶子节点往上却只有一条路径;对于递归,有一点我们需要注意递归和栈是类似的,最先执行的函数总是最后结束(在它之后调用的函数执行完之后它才能结束)

之前第一题我们是在遍历叶子节点的时候判断时候存在路径,那现在我们是不是可以通过叶子节点回溯呢?一个简单的思路是我们把所有满足条件(leaf->val == sum)的叶子节点push进vector,然后再从叶子节点向上找到路径。

讲到这里可能大家还是不太理解,因为表达能力的问题我也不知道该怎么讲清楚,但是大家一定要在看代码的时候自己模拟递归调用是怎么一个过程。

废话不多说,先看代码。

3.代码实现

我们先看看完整的代码

vector<vector<int> > pathSum(TreeNode* root, int sum) {
vector<vector<int> > paths;
if (root == NULL) {
return paths;
} else if (root->left == NULL && root->right == NULL && root->val == sum) {
vector<int> path;
path.push_back(root->val);
paths.push_back(path);
return paths;
}
paths = pathSum(root->left, sum - root->val);
vector<vector<int> > path_temp = pathSum(root->right, sum - root->val);
paths.insert(paths.end(), path_temp.begin(), path_temp.end());
for (int i = 0; i< paths.size(); i++) {
if (paths[i].size() == 0) {
paths.erase(paths.begin() + i);
} else {
paths[i].insert(paths[i].begin(), root->val);
}
}
return paths;
}


代码上面部分和前一题差不多,只是添加了一个push方法,将满足条件的叶子节点push进vector里

vector<vector<int> > paths;
if (root == NULL) {
return paths;
} else if (root->left == NULL && root->right == NULL && root->val == sum) {
vector<int> path;
path.push_back(root->val);
paths.push_back(path);
return paths;
}


paths指左子树返回的结果(因为懒就懒得改了),path_temp是右子树返回的结果,insert方法是将左右子树的结果合并

paths = pathSum(root->left, sum - root->val);
vector<vector<int> > path_temp = pathSum(root->right, sum - root->val);
paths.insert(paths.end(), path_temp.begin(), path_temp.end());


最后的部分是将其中size为0的vector去掉,一定要注意,size为0代表从叶子节点就不满足

for (int i = 0; i< paths.size(); i++) {
if (paths[i].size() == 0) {
paths.erase(paths.begin() + i);
} else {
paths[i].insert(paths[i].begin(), root->val);
}
}


对于代码运行的过程大家一定要在头脑里模拟运行一下,有些很玄的东西多想想才能理解。

4.结束

这个方法的关键在于了解二叉树和递归的某些特点,至于我是怎么想到的我也不知道,也许是突然开窍…所以导致我现在也解释不清楚代码了…不过,多模拟一下函数实际运行的情况对于理解递归有很大帮助!

有任何问题欢迎在评论区留言。

4000
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  二叉树 递归 leetcode
相关文章推荐