【问题标题】:complexity for recursive functions (Big O notation)递归函数的复杂性(大 O 表示法)
【发布时间】:2016-07-18 04:01:52
【问题描述】:

我有两个要确定其复杂性的函数。

第一个我只需要知道我的解决方案是否正确,第二个是因为我正在努力寻找解决方案的两个递归调用,如果可能的话最好进行解决,以便我可以学习它是如何完成的。

第一:

def sum(list):
    assert len(list)>0
    if len(list) == 1:
        return list[0]
    else:
        return sum(list[0:-1]) + list[-1]

尝试的解决方案:

T(0) = 4
T(n) = T(n-1) + 1 + c -- True for all n >0 

T(n) = T(n-1) + 1 + c
     = T(n-2) + 2 + 2C
     = T(n-k) + k = kC --(n-k = 0 implies that k=n)
T(n) = T(0) + n + nC
     = T(0) + 2nC --(T0 is nothing but 4)
     = 6nC
Complexity = O(n)  

第二:

def binSum(list):
    if len(list) == 1:  
        return list[0]
    else:
        return binSum(list[:len(list)//2]) + binSum(list[len(list)//2:])

任何帮助将不胜感激。

问候

【问题讨论】:

  • n+nc = n²c 怎么样?另外,首先你写T(0) = 4 然后“T(0) is nothing but 1”。它不会改变结果,但它是不一致的。也许你想告诉我们你对第二个函数的猜测。
  • 为错误道歉,从 T(n) = T(0) + n + nc 继续: =T(0) + 2nc -- (T) 只不过是 4) =4+ 2nc =6+nc 复杂度 O(n) ??
  • 没错。您可以将其编辑到您的问题中。第二个函数呢?
  • 我发现将递归函数转换为非递归函数然后计算复杂度更容易(通常,如果可能的话,它几乎总是如此)。对于您的第二个问题,请尝试将其更改为非递归循环,看看复杂度是多少(我想它会是 O(n Log(n)),但我没有计算过,所以我可能错了)。跨度>

标签: time-complexity big-o


【解决方案1】:

对于第一种情况,您可以使用递归函数 T(n) = T(n-1) + O(1)T(0) = O(1) 对时间复杂度进行建模。这显然解决了T(n) = O(n)

这是一个更直接、更正式的归纳证明。基本情况很简单:T(0)<=C 定义为O(1)。对于归纳步​​骤,假设 T(k) <= C*k 代表所有 k<=n 一些绝对常数 C>0。现在T(n+1) <= D + T(n) <= D + C*n <= max(C,D)*(n+1) 通过归纳假设,其中D>0 是一个绝对常数。

对于第二种情况,您可以使用T(n) = T(n/2) + T(n/2) = 2T(n/2)n>1T(1)=O(1) 建模时间复杂度。这通过master theorem 解决了T(n)=O(n)

【讨论】: