二叉树遍历的时间效率

时间:2014-11-09 03:11:07

标签: java performance time

这是一个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;
    }
  }

1 个答案:

答案 0 :(得分:0)

列表是一个对象。如果将List传递给方法,它将被视为该方法中的局部变量。在您的方法结束时,该局部变量将被垃圾收集(删除)。

您向List添加一个节点,然后以递归方式调用该方法传递该List。当你最终击中琐碎的案件(你打了一片叶子)。您的方法将结束并返回以继续运行调用它的(相同)方法。你没有返回任何东西,List的实例将被垃圾收集(删除)。这意味着列表中缺少叶子(因为删除了它的本地列表)。它将继续这样做,并且您的pathSum方法最终将返回一个空List。我不知道为什么它超出了时间限制,但你的代码不正确。

请注意,在Solution中,该方法返回添加新节点的List。所以调用它的方法存储了它。在您的实现中,您什么也不返回,并且调用它的方法没有使用新节点存储List,因此是垃圾回收。

我希望这能澄清你的问题。如果没有随时让我知道。