Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 求二叉树高度的递推关系和时间复杂度_Algorithm_Recursion_Binary Tree_Big O_Recurrence - Fatal编程技术网

Algorithm 求二叉树高度的递推关系和时间复杂度

Algorithm 求二叉树高度的递推关系和时间复杂度,algorithm,recursion,binary-tree,big-o,recurrence,Algorithm,Recursion,Binary Tree,Big O,Recurrence,我正在研究一个简单的问题,在HackerRank上查找二叉树的高度。我下面的解决方案通过了所有测试用例,在手工运行了一些代码之后,我相信它是一个O(n)解决方案。我在网上找到的大多数其他解决方案(我想)都说它也是O(n),但我无法根据这两种解决方案解决达到O(n)的递归关系 假设树不平衡,下面是我的解决方案: public static int height(Node root) { // Write your code here. if (root.left == null

我正在研究一个简单的问题,在HackerRank上查找二叉树的高度。我下面的解决方案通过了所有测试用例,在手工运行了一些代码之后,我相信它是一个O(n)解决方案。我在网上找到的大多数其他解决方案(我想)都说它也是O(n),但我无法根据这两种解决方案解决达到O(n)的递归关系

假设树不平衡,下面是我的解决方案:

 public static int height(Node root) {
    // Write your code here.
    if (root.left == null && root.right == null) {
      return 0;
    } else if (root.left == null && root.right != null) {
      return 1 + height(root.right);
    } else if (root.left != null && root.right == null) {
      return 1 + height(root.left);
    } else {
      return 1 + Math.max(height(root.left), height(root.right));
    }
  }
我发现调用的函数数几乎与节点数完全相同,这意味着它应该是O(n)。基于我的上一个案例,我认为这可能是最糟糕的运行时案例,当我需要在两个分支上调用height(node)时,我尝试推导以下递归关系

Let n be the number of nodes and k be the number of level
T(n) = 2 T(n/2)

Base Case: n = 0, n =1

T(0) = -1
T(1) = T(2^0)= 0

Recursive Case:
k = 1, T(2^1) = 2 * T(1)
k = 2, T(2^2) = 2 * T(2) = 2 * 2 * T(1) = 2^2 T(1)
k = 3, T(2^3) = 2^3 * T(1)
....
2^k = n=> k = logn => T(2^k) = 2^k * T(1) = 2^logn * T(1)  
显然,对我来说,时间复杂度是O(2^logn),我不明白为什么人们说它是O(n)?我读了这篇文章(),我想这是有道理的,因为
O(n)>O(2^logn)
,但我有两个问题:

  • 我的递归关系正确吗?结果正确吗?如果是,为什么在现实中(我计算函数被调用的次数)我仍然得到O(n)而不是O(2^logn)

  • 对于这样的递归函数,如何推导递归关系?你是否考虑了最坏的情况(在我的例子中是最后一个条件)并从中导出了递归关系

  • 由于
    2^log(n)=n
    根据
    log
    函数的定义,您可以发现两者是相同的。这意味着
    O(n)
    O(2^log(n))
    是等价的


    此外,如果您需要重复查找树的高度,您可以对树进行预处理并存储每个节点的子树高度,以便在预处理阶段后在
    O(1)
    中查找树的高度。

    精确地
    log
    表示对底的对数
    2
    。所以
    2^log(n)=x=>log(n)。log(2)=log(x)=>log(n)=>log(x)=>x=n。因此O(2^log(n))=O(n)
    -只是想添加解释。计算循环次数不是一个坏的练习,但对于这个问题,它不是必需的。搜索访问每个节点,并在每个节点上花费固定时间。因此,它必须是ω(n)。