二叉树遍历的时间效率



这是一个leetcode问题。"给定一个二叉树和一个和,找到所有根到叶的路径,其中每个路径的和等于给定的和。"但我的代码无法通过测试用例,因为时间超过了限制。但解决方案代码(https://oj.leetcode.com/discuss/15169/14-line-solution-in-java-using-recursion)可以通过测试用例。我不知道两个版本代码有什么大区别吗?

我的代码:

public class Solution {
  List<List<Integer>> res = new ArrayList<List<Integer>>();
  public List<List<Integer>> pathSum(TreeNode root, int sum) {
    if (root == null)
        return res;
    List<Integer> t = new ArrayList<Integer>();
    has(root, sum, t);
    return res;
  }
  public void has(TreeNode root, int sum, List<Integer> t) {
    if (root == null)
        return;
    if (root.left == null && root.right == null && sum == root.val) {
        t.add(root.val);
        res.add(t);
        return;
    }
    t.add(root.val);
    has(root.right, sum - root.val, t);
    has(root.left, sum - root.val, t);
    return;
  }
} 

解决方案:

public class Solution {
    public static List<List<Integer>> pathSum(TreeNode root, int sum) {
      List<List<Integer>> list = new ArrayList<List<Integer>>();
      if(root==null) return list;
      if (root.val==sum && root.left==null && root.right==null)   {
        list.add(new ArrayList<Integer>());
        list.get(list.size()-1).add(root.val);
        return list;
      }
      list.addAll(pathSum(root.left, sum-root.val));
      list.addAll(pathSum(root.right, sum-root.val));
      for(List<Integer> l:list)
          l.add(0, root.val);
      return list;
    }
  }
List是一个对象。如果将List传递给方法,它将被视为该方法中的局部变量。在方法结束时,该局部变量将被垃圾收集(删除)。

将一个节点添加到List中,然后递归地调用传递该List的方法。当你最终遇到琐碎的情况时(你碰到了一片树叶)。您的方法将结束并返回以继续运行调用它的(相同)方法。您没有返回任何内容,List的实例将被垃圾收集(删除)。因此,这意味着叶从您的列表中丢失(因为拥有它的本地列表已被删除)。它将继续这样做,并且您的pathSum方法最终将返回一个空List。我不知道为什么它超过了时间限制,但你的代码不正确。

请注意,在Solution中,该方法返回添加了新节点的List。因此,调用它的方法将其存储起来。在您的实现中,您什么都不返回,并且调用它的方法没有将List与新的Node一起存储,因此是垃圾收集的。

我希望这能澄清你的问题。如果没有空,请告诉我。

最新更新