zoukankan      html  css  js  c++  java
  • Leetcode: 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,
                  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 }
  • 相关阅读:
    第四周作业
    第三周作业
    第二周作业
    互联网公司采用增量模型做开发的优势
    面向过程分析方法与面向对象分析方法到底区别
    项目测试中的黑盒测试和白盒测试
    立项说明书里面的项目概述。
    项目开发中的一些问题
    面向对象之我见
    [自翻]fasthttp中文文档(持续更新)
  • 原文地址:https://www.cnblogs.com/EdwardLiu/p/3746875.html
Copyright © 2011-2022 走看看