✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:剑指offer系列题解
📝原题地址:题目地址
📣专栏定位:为找工作的小伙伴整理常考算法题解,祝大家都能成功上岸!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪
题目描述
输入一棵二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。
从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。
保证树中结点值均不小于 0。
数据范围
树中结点的数量 [0,1000]。
样例
给出二叉树如下所示,并给出num=22。 5 / \ 4 6 / / \ 12 13 6 / \ / \ 9 1 5 1 输出:[[5,4,12,1],[5,6,6,5]]
方法一:dfs O(n)
思路如下:
- 递归寻找满足条件的路径,每次递归时都将
sum
减去当前递归到的结点的值,如果此时已经到了叶子结点即左右指针都为空且sum
刚好为0
,则该路径满足要求,直接加入到二维数组ans
当中。 - 在递归的过程中要更新
dis
路径,遍历到该结点就加入路径当中,遍历完该结点就从dis
中删除掉它。
我们拿题目样例举例,来看看是如何实现的:
第一步: 遍历结点 5
,此时 sum = 22 - 5 = 17
。
第二步: 遍历结点 4
,此时 sum = 17 - 4 = 13
。
第三步: 遍历结点 12
,此时 sum = 13 - 12 = 1
。
第四步: 遍历结点 9
,此时 sum = 1 - 9 = -8
,并且已经到达叶子结点,但是该路径和不等于 22
,故不能加入答案 ans
中。
第五步: 回溯再遍历结点 1
,此时 sum = 1 - 1 = 0
,并且已经到达叶子结点,路径 [5,4,12,1]
之和等于 22
,故加入 ans
中。
第六步: 按照上述操作,继续遍历根结点的右子树,同样可以得到另一个路径 [5,6,6,5]
之和也是等于 22
,故也加入 ans
之中。
第七步: 返回 ans
数组即可。
/**
* 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>> ans;
vector<int> dis;
void dfs(TreeNode* root, int sum)
{
if (!root) return;
sum -= root->val; //减去当前值
dis.push_back(root->val);
//如果满足条件,则将dis加入到ans中
if (!root->left && !root->right && !sum) ans.push_back(dis);
dfs(root->left, sum); //遍历左子树
dfs(root->right, sum); //遍历右子树
dis.pop_back();
}
vector<vector<int>> findPath(TreeNode* root, int sum) {
if (!root) return {};
dfs(root, sum);
return ans;
}
};
欢迎大家在评论区交流~