剑指 Offer 34. 二叉树中和为某一值的路径
给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。
叶子节点 是指没有子节点的节点。
输入:root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
输出:[[5,4,11,2],[5,8,4,5]]
思路很简单,普通的深度优先遍历,值得注意的是一些“回复现场”的小细节。
简单点说,注意 你的代码中是否在各种条件下都有完整地“恢复现场”。
比如下面这个(我自己写的错误版本,卡了好久才找到毛病出在哪里)
shu-qian-d3
疏浅
来自江苏
7 小时前
请问大佬们,这个代码为什么测试用例不通过?提交显示,已经通过了110/114个 输入 [5,4,8,11,null,13,4,7,2,null,null,5,1] 22 输出 [[5,4,11,2],[5,4,8,4,5]] 预期结果 [[5,4,11,2],[5,8,4,5]] 我不明白,为什么第二个子解,‘4’没有从path里删除……很迷惑
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int target) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<Integer>();
f(root,0,target,path,ans);
return ans;
}
public void f(TreeNode root, int sum,int target,LinkedList<Integer> path,List<List<Integer>> ans){
if(root==null){return;}
path.addLast(root.val);
sum+=root.val;
if(sum==target&&root.right==null&&root.left==null){
List<Integer> temp = new ArrayList<>();
for(Integer i:path){
temp.add(i);
}
ans.add(temp);
return;
}
f(root.left,sum,target,path,ans);
f(root.right,sum,target,path,ans);
path.pollLast();//root.val
sum-=root.val;
}
}
我自己的回答:
@疏浅 我明白了,遍历到’2’时,收集到答案后直接return,但没有
恢复现场,导致后面退回到节点11时,path.pollLast的结果是’2’,这就和前面的遍历子结果不一致了。
解决方案,删除掉收集子答案后的return语句。具体如下:
public List<List<Integer>> pathSum(TreeNode root, int target) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<Integer>();
f(root,0,target,path,ans);
return ans;
}
public void f(TreeNode root, int sum,int target,LinkedList<Integer> path,List<List<Integer>> ans){
if(root==null){return;}
path.addLast(root.val);
sum+=root.val;
if(sum==target&&root.right==null&&root.left==null){
List<Integer> temp = new ArrayList<>();
for(Integer i:path){
temp.add(i);
}
ans.add(temp);
}
f(root.left,sum,target,path,ans);
f(root.right,sum,target,path,ans);
path.pollLast();
sum-=root.val;
}
或者,如下:(我参考了前面同学的代码)
public List<List<Integer>> pathSum(TreeNode root, int target) {
List<List<Integer>> ans = new ArrayList<>();
LinkedList<Integer> path = new LinkedList<Integer>();
f2(root,0,target,path,ans);
return ans;
}
public void f2(TreeNode root,int sum, int target, LinkedList<Integer> path, List<List<Integer>> ans){
if(root==null){
return;
}
if(root.left==null && root.right==null && sum+root.val==target){
// 注意:这里root.val没有 “加进” sum中,所以sum也无需回复现场——减去root.val
path.addLast(root.val);
ans.add(new ArrayList(path));
path.pollLast();
return;// 因为在这个if语句块中,已经完整地恢复了现场,所以可以return.
}
path.addLast(root.val);
sum+=root.val;
f2(root.left,sum,target,path,ans);
f2(root.right,sum,target,path,ans);
path.pollLast();
sum-=root.val;
}