#113
中等
低频
回溯路径总和 II
这是一道围绕树、二叉树展开的高频练习。建议先掌握「回溯」这套写法,再结合下方步骤讲解理解状态维护、边界处理和复杂度取舍。
树
二叉树
题目分析
这道题表面上是在处理「路径总和 II」,但先要想清楚题目到底让你返回什么,以及过程中哪些约束必须一直满足。从题型上看,它主要在考 树、二叉树 这些能力。这类题更像在一棵决策树里向下展开,关键是递归时带什么状态、什么时候回退。只有先把题目要求翻译成人话,后面的推荐代码才是在实现思路,而不是直接给答案。
接下来怎么看推荐代码: 带着这个理解再看推荐代码时,重点观察这条主线:DFS 过程中维护当前路径和路径数组,走到叶子节点时判断是否刚好等于目标和。
推荐代码
推荐解法:回溯
时间复杂度: O(n)
空间复杂度: O(h)
核心思路: DFS 过程中维护当前路径和路径数组,走到叶子节点时判断是否刚好等于目标和。
// 二叉树节点定义
class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
TreeNode(int val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
}
class Solution {
// 存储所有满足条件的路径
List<List<Integer>> res = new LinkedList<>();
// 存储当前路径
LinkedList<Integer> path = new LinkedList<>();
public List<List<Integer>> pathSum(TreeNode root, int targetSum) {
// 调用回溯函数
backtrack(root, targetSum);
return res;
}
// 回溯函数
private void backtrack(TreeNode root, int targetSum) {
// 如果节点为空,直接返回
if (root == null) return;
// 将当前节点值加入路径
path.add(root.val);
// 目标值减去当前节点值
targetSum -= root.val;
// 如果当前是叶子节点且路径和等于目标值
if (targetSum == 0 && root.left == null && root.right == null) {
// 将当前路径的副本加入结果集
res.add(new LinkedList<Integer>(path));
}
// 递归遍历左子树
backtrack(root.left, targetSum);
// 递归遍历右子树
backtrack(root.right, targetSum);
// 回溯:移除当前节点值
path.removeLast();
}
}结构化讲解
面试时怎么讲
开场思路
这题我会用 DFS 回溯,同时维护路径和当前路径数组。
核心过程
- 访问节点时先把它加入路径。
- 递归去左右子树时同步扣减目标和。
- 如果走到叶子且剩余和刚好为当前节点值,就收集答案。
- 返回上一层前要把当前节点从路径里移除。
复杂度总结
时间复杂度 O(n),空间复杂度主要是递归深度 O(h)。
面试补一句:这题比 Path Sum I 多出来的核心状态,就是“当前路径本身”。
核心思路
路径总和 II 需要返回完整路径,不只是判断真假,所以递归里除了剩余和,还要同步维护当前路径。
步骤讲解
1
进入节点时先把它加入路径
每访问一个节点,就把它值加入当前路径。
为什么这样做:如果最终命中叶子,这条路径要完整保存下来。
对应代码提示:path.add(node.val);
2
到叶子时判断是否命中目标
若当前节点是叶子且路径和刚好满足 target,就复制路径加入答案。
为什么这样做:只有根到叶路径才是题目要求的合法路径。
对应代码提示:if (node.left == null && node.right == null && remain == node.val) ...
3
递归返回时撤销当前节点
处理完左右子树后,把当前节点从路径中弹出。
为什么这样做:回溯必须恢复现场,供兄弟分支复用。
对应代码提示:path.remove(path.size() - 1);
易错点
把中间路径直接存引用
后续回溯会继续修改同一数组,导致答案被污染。
正确理解:加入答案时要复制当前路径。
只判断路径和,不判断是否叶子
会把中途节点也错算成答案。
正确理解:必须同时满足“叶子节点 + 和相等”。
忘记回溯删除当前节点
路径会串到后续分支里。
正确理解:递归退出前固定执行一次路径弹出。
复杂度与适用判断
时间复杂度:O(n)
空间复杂度:O(h)
比其他方案更好在哪里:比先搜所有路径再筛选更直接。
适用判断:树题若要求返回所有合法路径,优先考虑 DFS + 路径回溯。
额外提醒
- 判断合法路径时,叶子条件和路径和条件缺一不可。
动画演示
如果你还没完全看懂,可以展开动画演示。
回溯动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
回溯动画演示
想看这段解法是怎么一步步运行的,可以展开动画继续观察。
准备就绪 - 输入二叉树(层级遍历)和目标值,然后点击开始
递归栈:
空栈
找到的有效路径:
暂无结果,点击开始按钮执行动画...
动画演示仅在桌面端提供,移动端请优先阅读推荐代码与结构化讲解。