在确定时间复杂度的时候,总是给输入赋予n等变量吗?

时间:2017-10-09 21:14:20

标签: recursion binary-tree big-o

这个长篇文章的简短版本是在确定时间复杂度时是否总是给输入赋予n等变量?如果没有,你还能如何定义变量?

我在下面留下我的问题的长版本以防万一它可以帮助任何人。

注意:我知道问题已被提出here,但我对答案不满意。接受的答案忽略了问题的一部分,即递归本质上创建了一个平衡的二叉树,而第二个答案错误地假定作者使用输入作为n的定义而不是二叉树中调用的级别数。 (虽然可能是正确的观点,即差异是n的定义,而且可能是作者滑倒或者只是让我感到困惑)

我在“破解编码面试”第6版中比较了这两个例子

第44-45页(VI Big O Recursive Runtime部分)

int f(int n){
  if (n <= 1){
    return 1;
  }
  return f(n-1) + f(n-1);
}

在这种情况下,作者将n定义为通过递归调用创建的级别数。

第49-50页(VI Big O例9)

假设输入是平衡的二叉搜索树

int sum(Node node){
  if(node == null){
      return 0;
  }
  return sum(node.left) + node.value + sum(node.right);
}

这里作者将n定义为树中节点的数量,并指出树的深度是log n。 (并且因为2 ^ logn等于其O(n)

所以这里是基于第一个例子中的输入的树的调用次数和深度

Input Calls Depth (author started counting from 0, used the term levels)
1     1     0
2     2     1
3     7     2
4     15    3
etc

我真的很困惑为什么作者能够选择树的深度为n,因为在过去我总是看到用作n的输入? (它也似乎毫无意义b / c,深度是输入减去1)问题的第二个答案是here实际上是否正确而不是作者通过使用n的正确定义作为输入?

在上面的第二个例子中,似乎合理的是n是树中的节点数,因此它的深度为n?

所以我想我是否在询问输入是否始终是定义n(或者您想要用作变量的任何术语)的正确标准?如果没有,你怎么能定义n?如果输入始终用于定义n,我会得到答案不同的原因。如果没有,我会感到困惑,因为示例1中的递归实际上创建了一个平衡的二叉树,因此也具有log n的深度。