【发布时间】:2013-12-07 09:48:05
【问题描述】:
我很难证明这两个递归代码的复杂性。我对他们有一些直觉。我认为第一个是 O(n),第二个是 O(nlogn)。这些是代码:
def max_v1(lst):
if len(lst)== 1:
return lst[0]
return max(lst[0], max_v1(lst[1:]))
def max_v2(lst):
if len(lst)== 1:
return lst[0]
l = max_v2(lst[:len(lst)//2])
r = max_v2(lst[len(lst)//2:])
return max(l, r)
【问题讨论】:
-
这真的取决于你是在谈论算法,还是实现。第一个的实现实际上是 O(N*N)!在实现中,但该算法可以递归编码,几乎与 O(N) 中的相同。原因是因为在python中,一个列表切片(
lst[1:])其实本身就是一个O(N-1)操作。 -
@mgilson:小心那个感叹号。尽管它在括号之外,但它看起来仍然很像阶乘。
-
@user2357112 -- 很公平。我把它放在那里是为了强调。不幸的是,我的 5 分钟编辑窗口现在消失了……:-/
-
我在谈论一个长度为 N 的列表的时间复杂度。我使用了一个递归树,发现深度是 O(n),现在由于切片它对每个级别进行 O(n- 1) 还是 O(1)?
-
@user2751595 切片是线性时间操作,而不是恒定时间。您正在为每个
O(n)级别做O(n)工作。特别是第一个的复杂性大约是O(1 + 2 + 3 + 4 + ...+ n-1) = O(n(n-1)/2) = O(n^2)。第二个是O(nlog(n)),因为您正在为每个O(log(n))级别进行O(n)工作。如果您使用start和end指针,则两个解决方案都将是O(n),但第二个解决方案将使用更少的堆栈深度,而第一个解决方案对于长于1000的列表将失败(由于默认递归限制) .
标签: python recursion complexity-theory