def f(L):
if len(L) < 1 billion:
return L
else:
return f(L[:len(L) // 2]) + f(L[len(L) // 2:])
L是大小为n的列表
我知道如果它是一个递归调用,那么它将是O(logn),但这里有两个递归调用。
但是当我开始在可视化工具上运行它时,它开始表现出更多的O(n)运行时。
在我看来,应该是O(logn + logn)= O(2logn)= O(logn)。我是对的吗?
答案 0 :(得分:1)
如果len(L)
至少为10亿,那么你的算法将是O(n),因为你将列表分成两部分,然后将这两部分重新加在一起。切片和添加都是O(n)操作。
如果要测试两个递归调用的运行时,
1。传入开始和结束索引,然后调用
f(L, start, start+(end-start)//2) + f(L, start+(end-start)//2, end)
2。 end-start
小于10亿时返回end-start
或其他一些O(1)
答案 1 :(得分:1)
考虑您正在做多少次通话。在递归的第一级,您将进行2次调用。对于每个人,你会再打两个电话。等等......这意味着在递归的i
级别,您将总共进行O(2^i)
个函数调用。
有多少级别的递归?这只是具有n
元素的二叉树的高度,即O(log_2 n)
。
因此,当您到达递归的所有叶子时,您将完成O(2^(log_2 n)) = O(n)
个函数调用。
-
另一种看待它的方式是你最终必须将整个列表重新组合在一起,那么你怎么能在不到O(n)
的时间内完成呢?