【问题标题】:Big O notation for fib recursionfib 递归的大 O 表示法
【发布时间】:2012-07-26 17:26:10
【问题描述】:

以下函数的 Big-O 运行时间是多少?解释一下。

static int fib(int n){
  if (n <= 2)
     return 1;
  else 
     return fib(n-1) + fib(n-2)
   }

另外,您将如何使用更快的 Big-O 运行时迭代地重写 fib(int n) 函数? 这是否是 O(n) 的最佳方式:

 public static int fibonacci (int n){
 int previous = -1;
 int result = 1;
 for (int i = 0; i <= n; ++i)
 {
 int sum = result + previous;
 previous = result;
 result = sum;
 }
 return result;
}
}

【问题讨论】:

  • 在 T(n) = c + T(n-1) + T(n-2) 中求解 T(n)。
  • T(n)= T(n-1) + T(n-2) + O(1) T(n)= O(2^n-1) + O(2^n -2) + O(1) = O(2^n) 是我所拥有的。只是仔细检查自己
  • 只是想全面了解如何使用大 O 和递归。
  • Big O 和递归不是特定于语言的,所以这不是一个真正的 java 问题。
  • 这有点晚了,因为有人已经给出了答案并且被接受了,但是仅仅陈述问题并要求答案通常是不好的。如果您陈述问题然后告诉我们您到目前为止有什么解决方案以及您不确定的确切内容会更好。 (我认为第二个代码 sn-p 可能是您的工作,所以我的评论主要针对您问题的第一部分)

标签: java algorithm big-o fibonacci


【解决方案1】:

证明

您将计算 Fib(n) 的时间函数建模为计算 Fib(n-1) 的时间加上计算 Fib(n-2) 的时间加上将它们加在一起的时间 (O(1))。

T(n&lt;=1) = O(1)

T(n) = T(n-1) + T(n-2) + O(1)

你解决这个递归关系(例如使用生成函数),你最终会得到答案。

或者,您可以绘制递归树,其深度为n,并直观地看出该函数是渐近的O(2n)。然后你可以通过归纳来证明你的猜想。

基地:n = 1 很明显

假设T(n-1) = O(2n-1)因此

T(n) = T(n-1) + T(n-2) + O(1)等于

T(n) = O(2n-1) + O(2n-2) + O(1) = O(2n)

迭代版本

请注意,即使这种实现也只适用于较小的 n 值,因为 Fibonacci 函数呈指数增长,而 32 位有符号 Java 整数只能保存前 46 个 Fibonacci 数

int prev1=0, prev2=1;
for(int i=0; i<n; i++) {
  int savePrev1 = prev1;
  prev1 = prev2;
  prev2 = savePrev1 + prev2;
}
return prev1;

【讨论】:

  • 正是我所拥有的。惊人的。谢谢您的帮助。只是想仔细检查一下。