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 sum.
给定一个二叉树和一个数字,找到所有从根结点到叶节点的路径,满足和和给定数字相等。
For example:
Given the below binary tree and sum = 22,
1
5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1
return
[ [5,4,11,2], [5,8,4,5] ]
public class TreeNode {
int val;
TreeNode left;
TreeNode right;
TreeNode(int x) { val = x; }
}
我的思路
采用递归的思路,可是在沿着二叉树进行深度搜索的同时,需要将沿途结点的值记录在一个list中,到叶子节点时要判断这条路径上所有结点的值的和是否和给定值相等;
若相等,则将这个list添加进结果集中;
若不等,则遍历其他路径;
关键点1:
理清递归的条理:
递归的两个重点:
* 求解主问题可以转换成求解子问题;
* 递归结束的条件;
关键点2:
深度搜索遍历的过程中,不仅要向list中添加结点值,还要注意删除结点值;
深度遍历时,向list中添加值;回溯时,从list中删除值。
关键点3:
result.add(new LinkedList(currentResult));
目前还不是很清楚为什么只能按照上面这样写,而写成result.add(currentResult);
这种不可以?
答疑:
因为result.add(currentResult);
currentResult是一个引用,它指向的是一块内存地址,而这块内存中的内容是在不断变化的,而且代码运行结束后,这块内存中的内容被清空,所以导致最后输出为空,即[ [ ] , [ ] ] 的形式,这样就应该写成result.add(new LinkedList(currentResult));
的形式。
我的方法
我自己的方法没有做出来,结果错误。
方法一
方法一用的是Arraylist,用Linkedlist、Stack都是可以的。
public List<List<Integer>> pathSum0(TreeNode root, int sum) {
List<List<Integer>> result = new ArrayList<>();
List<Integer> list = new ArrayList<>();
path0(root, sum, result, list);
return result;
}
public void path0(TreeNode root, int sum, List<List<Integer>> result, List<Integer> list){
if(root == null) return;
list.add(root.val);
if(root.left == null && root.right == null && root.val == sum){
//result.add(list);
result.add(newArrayList(list));//这里为什么上面一行输出结果就是两个空list,要这样才行???
}
else{
path0(root.left, sum - root.val, result, list);
path0(root.right, sum - root.val, result, list);
}
list.remove(list.size()-1);
}
方法二
方法二和上面方法一的思路是一样的,只是书写方式不一样,加深对递归方法的认知。
public List<List<Integer>> pathSum5(TreeNode root, int sum) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
dfs(root, sum, res, path);
return res;
}
public void dfs(TreeNode root, int sum, List<List<Integer>> res, List<Integer> path){
if(root==null) return;
path.add(root.val);
if(root.left==null && root.right==null ){
if(root.val==sum)
res.add(new ArrayList<Integer>(path));
return;
}
if(root.left!=null) {
dfs(root.left,sum-root.val,res,path);
path.remove(path.size()-1);
}
if(root.right!=null) {
dfs(root.right,sum-root.val,res,path);
path.remove(path.size()-1);
}
}
方法三
public List<List<Integer>> pathSum4(TreeNode root, int sum) {
List<List<Integer>> res = new ArrayList<>();
List<Integer> path = new ArrayList<>();
Stack<TreeNode> stack = new Stack<TreeNode>();
int SUM = 0;
TreeNode cur = root;
TreeNode pre = null;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
path.add(cur.val);
SUM += cur.val;
cur = cur.left;
}
cur = stack.peek();
if (cur.right != null && cur.right != pre) {
cur = cur.right;
continue;
}
if (cur.left == null && cur.right == null && SUM == sum)
res.add(new ArrayList<Integer>(path));
pre = cur;
stack.pop();
path.remove(path.size() - 1);
SUM -= cur.val;
cur = null;
}
return res;
}