【问题标题】:Time efficiency of binary tree traversal二叉树遍历的时间效率
【发布时间】:2014-11-09 03:11:06
【问题描述】:

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

【问题讨论】:

    标签: java performance time


    【解决方案1】:

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

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

    请注意,在解决方案中,该方法返回添加新节点的列表。所以调用它的方法将它存储起来。在您的实现中,您没有返回任何内容,并且调用它的方法没有将 List 与新节点一起存储,因此被垃圾收集。

    我希望这可以澄清您的问题。如果没有,请随时告诉我。

    【讨论】:

    • 当我的代码遇到叶子时,我会将结果保存到全局变量“res”中。我认为我的代码符合逻辑。
    • 不,这不是真的,你没有在 res 中存储任何东西。你的想法是对的,但你执行错了。
    • 哦,等等,我又快速查看了您的代码,您是对的。等等,让我找出你的错误。
    • 你说得对Auberon,我的代码有错误,对于参数t,如果我改变它,即使我从递归中返回,我也会得到改变的那个。所以我修改的是做一个(t)的副本,并在副本上进行更改。然后我通过了测试用例。感谢您的帮助。
    猜你喜欢
    • 2012-01-01
    • 2022-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多