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
这是一道很常见的题,看题的时候看漏了root to leaf的leaf,以为只要从root开始就可以了,太不仔细了,sigh~ 其实类似的题目在Career Cup的4.9,那个题是任意路径,不必从root到leaf,要求更高。
一直以来我都有这样的疑问,迭代的变量(如下例中的path、total)如果在迭代中发生改变,返回上一层进行新的迭代的时候,调用这个变量,是用新的改变后的那个变量呢,还是用原来的?比如:
1 public void getpath(ArrayList<ArrayList<Integer>> paths, ArrayList<Integer> path, int total, TreeNode root, int sum) { 2 if (root == null) return; 3 path.add(root.val); 4 total = total + root.val; 5 if (total == sum && root.left == null && root.right == null) { 6 paths.add(new ArrayList<Integer>(path)); 7 } 8 getpath(paths, path, total, root.left, sum); 9 getpath(paths, path, total, root.right, sum); 10 path.remove(path.size() - 1); 11 total = total - root.val; 12 }
比如这段代码中root.left和root.right的两段recursion,这个recursion中会对path和total进行改变。我在想,如果这两段迭代完了之后,返回上一层,上一层进行新的迭代,是不是使用update了之后的path和total呢?
对java而言答案是的。任何分支对path变量的改变将要被保留。path变量始终只有唯一的一个,而不存在拷贝什么的,如果在root.left的recursion中改变了path,进入root.right的recursion,path变量就已经是新的path变量了!(关于这个java函数参数的问题我现在一直存疑,)
这一点和C恰恰相反,众所周知C语言函数用形参去拷贝实参,用形参进行一系列运算之后即使发生改变,不会对实参造成任何影响,实参还是原来的那个。所以如果上述例子是在C语言中,path就还是原来那一个!如果你想要path变化,就得用path的地址
正因为java中,任何分支对变量的改变会保存下来,所以我们才在末尾要加上path.remove(path.size() - 1); 以便能够尝试新的可能性。
推荐代码:
1 public class Solution { 2 public ArrayList<ArrayList<Integer>> pathSum(TreeNode root, int sum) { 3 ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>(); 4 if(root==null) 5 return res; 6 ArrayList<Integer> item = new ArrayList<Integer>(); 7 helper(root,sum,item,res); 8 return res; 9 } 10 private void helper(TreeNode root, int sum, ArrayList<Integer> item, ArrayList<ArrayList<Integer>> res) 11 { 12 if(root == null) 13 return; 14 if(root.left==null && root.right==null) 15 { 16 if (root.val == sum) { 17 item.add(root.val); 18 res.add(new ArrayList<Integer>(item)); 19 item.remove(item.size()-1); 20 } 21 return; 22 } 23 if(root.left!=null) 24 { 25 item.add(root.val); 26 helper(root.left,sum-root.val,item,res); 27 item.remove(item.size()-1); 28 } 29 if(root.right!=null) 30 { 31 item.add(root.val); 32 helper(root.right,sum-root.val,item,res); 33 item.remove(item.size()-1); 34 } 35 } 36 }