【问题标题】:Calculating node depths of all nodes in a Binary Tree计算二叉树中所有节点的节点深度
【发布时间】:2021-01-02 14:43:04
【问题描述】:

我正在尝试解决Node Depths question from Algoexpert。该问题要求您计算给定二叉树中所有节点的深度之和。例如,给定这棵树 -

          1
       /     \
      2       3
    /   \   /   \
   4     5 6     7
 /   \
8     9

总和应该是 16。

我为它写了一个递归解决方案,我认为这是正确的,但有趣的是,只有第一个测试通过,而其余的测试用例失败。这是我的解决方案-

import java.util.*;

class Program {

  // static variable to hold the final sum
  private static int finalSum = 0;

  public static int nodeDepths(BinaryTree root) {
        // Write your code here.
        int runningSum = 0;
        depthHelper(root.left, runningSum);
        depthHelper(root.right, runningSum);
        return finalSum;
  }
    
    private static void depthHelper(BinaryTree node, int runningSum) {
        if(node == null) return;
        runningSum++;
        finalSum += runningSum;
        depthHelper(node.left, runningSum); 
        depthHelper(node.right, runningSum);
    }

  static class BinaryTree {
    int value;
    BinaryTree left;
    BinaryTree right;

    public BinaryTree(int value) {
      this.value = value;
      left = null;
      right = null;
    }
  }
}

算法本身相当简单。

有一个runningSum 变量(初始化为-1 以说明根),每次我访问一个新节点(即:从它的父节点向下一级)时,我都会向该变量添加1。而且,这个runningSum 变量的值会在每次递归调用时添加到finalSum 变量中。

例如,在节点 2 处,runningSum1,这会添加到 finalSum,即 0。现在finalSum 变为1。节点3 相同,之后finalSum 变为2。在节点4runningSum 变为2finalSum 变为4

第一个测试用例通过,我收到这条消息 -

但是,随后的所有案例都失败了。我认为可能发生的事情是 - 前一个测试用例执行的输出没有被清除,并且以某种方式被添加到当前测试用例执行的结果中。

这就是为什么我认为这可能是原因 -

 1. Test case 2 - our code output - 0,  your code output - 16
 2. Test case 3 - our code output - 1,  your code output - 17
 3. Test case 4 - our code output - 2,  your code output - 19
 4. Test case 5 - our code output - 4,  your code output - 23
 5. Test case 6 - our code output - 21,  your code output - 44
 6. Test case 7 - our code output - 42,  your code output - 86

注意前一次执行的结果如何未被清除并被添加到后续执行的“我们的代码输出”中。例如,在第二个测试用例中,“你的代码输出”结果显示16,这实际上是第一个测试用例的结果。

这是因为在代码中使用了全局static 变量吗?但是我在 Leetcode 上多次使用了相同的方法,并且效果很好。

或者我的算法中是否存在其他错误?

PS - 我知道这里不赞成使用屏幕截图,但有可能这是特定于平台的问题,所以我不得不使用它。

【问题讨论】:

  • nodeDepths() 末尾尝试int temp=finalSum; finalsum=0; return temp;
  • 是的!那行得通,所有测试用例都通过了,谢谢!所以这是一个特定于平台的问题。他们的测试运行方式到底有什么问题,所以我可以提交错误报告?
  • 也许他们只用你班级的一个对象运行测试。是的,我认为你应该举报!
  • 我宁愿将 finalSum 也初始化为 0,而不是使用临时变量。请注意,如果请求是并行发出的,则此实现不起作用。

标签: java algorithm recursion binary-tree


【解决方案1】:

在我看来,发生这种行为并不是一个错误。这是由于使一切都静止了。有很多方法可以避免这个问题。其中两个在这里解释:

使用静态方法但使用无状态类:

public static int nodeDepths(BinaryTree root) {
    // Write your code here.
    return depthHelper(root.left, 1) + depthHelper(root.right, 1);
}

private static int depthHelper(BinaryTree node, int sum) {
    if (node == null) return 0;
    return sum + depthHelper(node.left, sum + 1) + depthHelper(node.right, sum + 1);
}

创建一个对象(如果您不只对对象执行一项操作,它会变得更有用):

public static int nodeDepths(BinaryTree root) {
    // Write your code here.
    return new Program().depthSum(root); // call to non-static method
    // like this you can use your original implementation, but the
    // class variable (finalSum) has to be non-static too
}

两种实现都是线程安全的。

【讨论】:

    【解决方案2】:

    看起来他们的测试平台使用您班级的一个对象运行测试。所以你应该在nodeDepths()方法的末尾清除finalSum

    public static int nodeDepths(BinaryTree root) {
        // Write your code here.
        int runningSum = 0;
        depthHelper(root.left, runningSum);
        depthHelper(root.right, runningSum);
        int temp=finalSum;  
        finalsum=0; 
        return temp;
    }
    

    【讨论】:

    • 在函数顶部将finalSum设置为0会更简单。
    猜你喜欢
    • 1970-01-01
    • 2020-07-19
    • 1970-01-01
    • 2020-10-24
    • 1970-01-01
    • 2011-06-20
    • 1970-01-01
    • 2023-03-25
    • 2021-10-10
    相关资源
    最近更新 更多