我试图弄清楚以下函数的最坏情况渐近时间复杂度:
let rec min = function
| [k] -> k
| k::ks -> if k <= min ks then k else min ks
我知道它效率不高,因为在第二次模式匹配中调用min两次。但是你怎么能找到这个功能更糟糕的情况呢?
答案 0 :(得分:6)
正如您所注意到的,min
功能是
在第二次模式匹配中调用min两次
在最坏的情况下(列表末尾的最小值),它会对列表的每个元素进行2次调用,每个元素再次为列表的尾部调用两次,...
因此复杂度为O(2 ^ n)。
如果您评估min ks
一次并使用该值,则复杂性将为O(n)。
let rec min = function
| [k] -> k
| k::ks ->
let minTail = min ks
if k <= minTail then k else minTail
答案 1 :(得分:3)
此函数的最坏情况是k
总是大于min ks
,如 [n,n-1,n-2 ... 1]
在这种情况下,您将在每次迭代中为阵列的其余部分运行min
两次,这等于:
T(n)= 2T(n-1)
T(n-1)= 2T(n-2)
T(n-2)= 2T(n-3)
...
T(1)= 1
回到T(n),我们可以看到:
T(n)= 2 * 2 * T(n-2)
= 2 * 2 * 2 * T(n - 3)
= 2 n
这就像它可能的那样糟糕。