下面的递归代码中的大(O)是O(n选择k)?
int nchoosek(int n, int k) {
if (n == k) return 1;
if (k == 0) return 1;
return nchoosek(n-1, k) + nchoosek(n-1, k-1);
}
答案 0 :(得分:1)
我不确定符号是否正确,但我想你可以写这个函数的重现,如
T(n) = T(n-1, k) + T(n-1, k-1) + O(1)
由于你有两条可能的路径我们只需要分析每种路径的最坏情况并选择最慢的路径。
T(n-1, k)
鉴于0<k<n
和k
尽可能远离n
,我们有
T(n-1, k) = T(n-1) = O(n)
T(n-1, k-1)
我们需要0<k<n
,k
应尽可能接近n
。然后
T(n-1, k-1) = T(n-1) = O(n)
因此T(n, k) = 2*O(n) + O(1) = O(n)
另一种看待这种情况的方法是将问题减少到其他已知问题,例如你可以通过使用因子函数的选择函数的定义来解决同样的问题:
nCk = n!/k!(n-k)!
即使在递归情况下,因子的运行时间也是O(n)
。
nCk
需要三次计算因子:
n! => O(n)
k! => O(k) = O(n)
(n-k)! => O(n-k) = O(n)
然后乘法和除法都是常数时间O(1)
,因此运行时间是:
T(n) = 3*O(n) + 2*O(1) = O(n)