【LeetCode】#112 #113 #437 Path Sum Series
2017-02-07 18:39
162 查看
首先要说明二叉树的问题就是用递归来做,基本没有其他方法,因为这数据结构基本只能用递归遍历,不要把事情想复杂了。
判断从树的根节点到叶子节点的路径中,是否有一条所有节点上的值之和和特定的数字,即
从根节点到叶子节点,线路的起点的是固定的,只需要不断递归下去,判断在叶子节点处是否满足根节点加到该节点的值之和为
这个限制条件把这个问题简化了很多很多。
要输出路径,在递归的过程中肯定是要有一个传址的变量
这里有一点搞不懂,为什么最后要进行
然后,发现如果这么写我是错的。对于下面的这一棵二叉树,得到的结果是
![](https://img-blog.csdn.net/20170207191749372?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMTMwNjQ1Mg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
如,左侧的
这里有两个递归函数,函数
#112 Path Sum
原题链接:https://leetcode.com/problems/path-sum/判断从树的根节点到叶子节点的路径中,是否有一条所有节点上的值之和和特定的数字,即
sum。
从根节点到叶子节点,线路的起点的是固定的,只需要不断递归下去,判断在叶子节点处是否满足根节点加到该节点的值之和为
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: bool hasPathSum(TreeNode* root, int sum) { if (!root) 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); } };
#113 Path Sum II
与前题要做的事情一致,只是现在要求输出路径。如果路径有多条,要求输出多条路径。要输出路径,在递归的过程中肯定是要有一个传址的变量
vector<int>将路径记录下来。有多条路径,需要把多条路径
vector<vector<int> >记录下来。
/** * 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> > paths; vector<int> path; pathSumHelper(root, sum, path, paths); return paths; } private: void pathSumHelper(TreeNode* root, int sum, vector<int>& path, vector<vector<int>>& paths) { if (root == NULL) return; path.push_back(root->val); if (root->val == sum && root->left == NULL && root->right == NULL) { paths.push_back(path); } pathSumHelper(root->left, sum - root->val, path, paths); pathSumHelper(root->right, sum - root->val, path, paths); path.pop_back(); } };
这里有一点搞不懂,为什么最后要进行
path.pop_back(),如果我把代码写成这样子:
void pathSumHelper(TreeNode* root, int sum, vector<int>& path, vector<vector<int>>& paths) { if (root == NULL) return; path.push_back(root->val); if (root->left == NULL && root->right == NULL) { if (root->val == sum) { paths.push_back(path); } path.pop_back(); } pathSumHelper(root->left, sum - root->val, path, paths); pathSumHelper(root->right, sum - root->val, path, paths); }
然后,发现如果这么写我是错的。对于下面的这一棵二叉树,得到的结果是
[[5,4,11,2],[5,4,11,8,4,5]],正确结果是
[[5,4,11,2],[5,8,4,5]]。第二条路径中多了
4, 11,问题出在只是把根节点去除掉,没有去除中间节点,使得中间节点及其子孙节点中的中间节点出现在了经过其兄弟节点的路径。
如,左侧的
4节点会留在右子树的路径中是因为,调用根节点的
pathSumHelper时,会调用两次
pathSumHelper(root->left/* node 4 */, sum - root->val, path, paths);、
pathSumHelper(root->right/* node 8 */, sum - root->val, path, paths);,在第一次调用完成之后,
path变量中的
4节点未被删除,所以存留在了路径
[5,4,11,8,4,5]中(就是第一个
4)。
#437 Path Sum III
继续,判断是否存在路径上的值之和为特定的数字sum。变化在于起点不固定、终点也不固定,值存在负数(其实无所谓,因为前面的代码没有判断数值超过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: int pathSum(TreeNode* root, int sum) { if (!root) return 0; return sumUp(root, 0, sum) + pathSum(root->right, sum) + pathSum(root->left, sum); } private: int sumUp(TreeNode* root, int pre, int sum) { if (!root) return 0; int current = pre + root->val; return (current == sum) + sumUp(root->right, current, sum) + sumUp(root->left, current, sum); // 如果当前节点能够满足条件,有一条路径了,但是还是要继续搜索左右子树,因为值不全为非负,这里返回的路径都具有同一个根节点。 } };
这里有两个递归函数,函数
pathSum的
return sumUp(root, 0, sum) + pathSum(root->right, sum) + pathSum(root->left, sum);是以该节点
root为起点的路径条数、以
root->right为起点或者以其子孙节点为起点的路径条数、以
root->left为起点或者以其子孙节点为起点的路径条数。
相关文章推荐
- leetcode之二叉树类之路径和系列-----112/113/124/257/437 path sum(牵扯附加OJ572和OJ100, 子树和子拓扑)
- [LeetCode 112 113] - 路径和I & II (Path Sum I & II)
- 【LeetCode】112,113,437. Path Sum I, II, III
- LeetCode(113) Path Sum II
- leetcode_question_113 Path Sum II
- Leetcode 笔记 113 - Path Sum II
- LeetCode113:Path Sum II
- LeetCode(113)Path Sum II
- LeetCode 437 Path Sum III
- 【LeetCode-面试算法经典-Java实现】【112-Path Sum(路径和)】
- leetcode(437):Path Sum III
- Leetcode 113 Path Sum II
- LeetCode(113) Path Sum II
- LeetCode 113: Path Sum II
- [Leetcode 113, Medium] Path sum II
- LeetCode 112, 123. Path Sum i, ii
- LeetCode 113: Path Sum II 二叉树遍历
- LeetCode 437 Path Sum III (DFS)
- leetcode_113_Path Sum II
- Leetcode 113, Path Sum II