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

这道二叉树路径之和在之前那道题 Path Sum 的基础上又需要找出路径,但是基本思想都一样,还是需要用深度优先搜索 DFS,只不过数据结构相对复杂一点,需要用到二维的 vector,而且每当 DFS 搜索到新结点时,都要保存该结点。而且每当找出一条路径之后,都将这个保存为一维 vector 的路径保存到最终结果二维 vector 中。并且,每当 DFS 搜索到子结点,发现不是路径和时,返回上一个结点时,需要把该结点从一维 vector 中移除,参见代码如下:

解法一:

class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
vector<int> out;
helper(root, sum, out, res);
return res;
}
void helper(TreeNode* node, int sum, vector<int>& out, vector<vector<int>>& res) {
if (!node) return;
out.push_back(node->val);
if (sum == node->val && !node->left && !node->right) {
res.push_back(out);
}
helper(node->left, sum - node->val, out, res);
helper(node->right, sum - node->val, out, res);
out.pop_back();
}
};

下面这种方法是迭代的写法,用的是中序遍历的顺序,参考之前那道 Binary Tree Inorder Traversal,中序遍历本来是要用栈来辅助运算的,由于要取出路径上的结点值,所以用一个 vector 来代替 stack,首先利用 while 循环找到最左子结点,在找的过程中,把路径中的结点值都加起来,这时候取出 vector 中的尾元素,如果其左右子结点都不存在且当前累加值正好等于 sum 了,将这条路径取出来存入结果 res 中,下面的部分是和一般的迭代中序写法有所不同的地方,由于中序遍历的特点,遍历到当前结点的时候,是有两种情况的,有可能此时是从左子结点跳回来的,此时正要去右子结点,则当前的结点值还是算在路径中的;也有可能当前是从右子结点跳回来的,并且此时要跳回上一个结点去,此时就要减去当前结点值,因为其已经不属于路径中的结点了。为了区分这两种情况,这里使用一个额外指针 pre 来指向前一个结点,如果右子结点存在且不等于 pre,直接将指针移到右子结点,反之更新 pre 为 cur,cur 重置为空,val 减去当前结点,st 删掉最后一个结点,参见代码如下:

解法二:

class Solution {
public:
vector<vector<int>> pathSum(TreeNode* root, int sum) {
vector<vector<int>> res;
vector<TreeNode*> st;
TreeNode *cur = root, *pre = nullptr;
int val = ;
while (cur || !st.empty()) {
while (cur) {
st.push_back(cur);
val += cur->val;
cur = cur->left;
}
cur = st.back();
if (!cur->left && !cur->right && val == sum) {
vector<int> v;
for (auto &a : st) v.push_back(a->val);
res.push_back(v);
}
if (cur->right && cur->right != pre) {
cur = cur->right;
} else {
pre = cur;
val -= cur->val;
st.pop_back();
cur = nullptr;
}
}
return res;
}
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/113

类似题目:

Path Sum

Path Sum IV

Path Sum III

Binary Tree Maximum Path Sum

Sum Root to Leaf Numbers

Binary Tree Preorder Traversal

Binary Tree Paths

参考资料:

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

https://leetcode.com/problems/path-sum-ii/discuss/36685/12ms-11-lines-C%2B%2B-Solution

https://leetcode.com/problems/path-sum-ii/discuss/36695/Java-Solution%3A-iterative-and-recursive

https://leetcode.com/problems/path-sum-ii/discuss/36683/DFS-with-one-LinkedList-accepted-java-solution

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Path Sum II 二叉树路径之和之二的更多相关文章

  1. [LeetCode] 113. Path Sum II 二叉树路径之和之二

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

  2. LeetCode 112. Path Sum (二叉树路径之和)

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

  3. [LeetCode] 113. Path Sum II ☆☆☆(二叉树所有路径和等于给定的数)

    LeetCode 二叉树路径问题 Path SUM(①②③)总结 Path Sum II leetcode java 描述 Given a binary tree and a sum, find al ...

  4. [LeetCode] Path Sum III 二叉树的路径和之三

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  5. [LeetCode] Path Sum IV 二叉树的路径和之四

    If the depth of a tree is smaller than 5, then this tree can be represented by a list of three-digit ...

  6. [leetcode]Path Sum II

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

  7. LeetCode: Path Sum II 解题报告

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

  8. LeetCode 437. Path Sum III (路径之和之三)

    You are given a binary tree in which each node contains an integer value. Find the number of paths t ...

  9. [Leetcode] Path Sum II路径和

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

随机推荐

  1. 【分布式】Zookeeper的服务器角色

    一.前言 前一篇已经详细的讲解了Zookeeper的Leader选举过程,下面接着学习Zookeeper中服务器的各个角色及其细节. 二.服务器角色 2.1 Leader Leader服务器是Zook ...

  2. 利用C#开发移动跨平台Hybrid App(一):从Native端聊Hybrid的实现

    0x00 前言 前一段时间分别读了两篇博客,分别是叶小钗兄的<浅谈Hybrid技术的设计与实现>以及徐磊哥的<从技术经理的角度算一算,如何可以多快好省的做个app>.受到了很多 ...

  3. 7.JAVA之GUI编程鼠标事件

    鼠标事件: 功能: 1.基本窗体功能实现 2.鼠标移动监听,当鼠标移动到按钮上时,触发打印事件. 3.按钮活动监听,当按钮活动时,触发打印事件. 4.按钮被单击时触发打印事件. 源码如下: impor ...

  4. MacOS平台下@rpath在动态链接库中的应用

    一.背景介绍 公司开发的一个底层库被用在了Mac平台的多个产品中.在开发这个底层库的初期,对于Mac OSX下的Install name 并没有过多的了解.对于XCode中的install name项 ...

  5. jQuery中怎样阻止后绑定事件

    你的代码在页面载入过程中已经完成事件绑定了,没有阻止后绑定的事件的办法了,不过可以删除当前指定节点的事件绑定.方法如下:$("#btn").click(function(){if( ...

  6. 前端开发:Javascript中的数组,常用方法解析

    前端开发:Javascript中的数组,常用方法解析 前言 Array是Javascript构成的一个重要的部分,它可以用来存储字符串.对象.函数.Number,它是非常强大的.因此深入了解Array ...

  7. java基础1.-------抽象类,抽象方法

    抽象类:抽象类不能实例化,类中的方法必须经过子类的重写实现 类里的方法是public修饰时,子类可重写也可不重写 类的方法是abstract修饰时,方法是抽象方法,子类必须重写该方法 类的方法用fin ...

  8. extend

    这段时间在写一个预览图片的插件, 被我老大说了无数次了,不多说啥,说多了都是泪 昨天看着我的代码他说你用了extend,那你知道是什么意思吗 我只知道是扩展的意思,瞬间觉得自己弱爆了 真的 然后今天看 ...

  9. eclipse SE增加Web开发插件

    最近接触了些java项目,之前安装了eclipse SE版本.没有Web开发插件,调试不了Web代码.点击“Window”--“Preference” 左边菜单栏是找不到“Server”项来配置服务器 ...

  10. 压缩html

    最近研究程序的优化,压缩html可以减小html的体积,有利于提高页面的相应速度.在webform的basepage中添加如下代码: /// <summary> /// 重写Render方 ...