我有两个版本的相同算法,递归地找到链表中的最小元素。一种算法首先检查是否已到达列表的末尾,如果是,则返回该元素,然后检查当前元素(列表的头部)是否小于递归调用的当前最小值。如果当前元素更大,则返回当前min(由递归调用找到)。
另一种算法的做法略有不同,在检查基本情况后,它将递归调用存储在临时变量中,然后使用temp与当前列表元素进行比较。
我发现第一种方法的复发是:
T(n)= 1T(n-1)+ O(1)
(我不太确定)
我无法弄清楚的是第二种算法的重现差异,因为它们似乎在做同样的事情。递归调用是否存储在临时变量中是否会为重复发生额外的工作?
两种算法的伪代码如下:
第一种方法
function min_list_1(L) // L is a non-empty list of numbers
if has_only_one_element(L): return L.head
if L.head < min_list_1(L.next): return L.head
else:
return min_list_1(L.next)
第二种方法
function min_list_2(L) // L is a non-empty list of numbers
if has_only_one_element(L): return L.head
temp = min_list_2(L.next)
if L.head < temp: return L.head
else:
return temp
答案 0 :(得分:4)
第一个将在大多数情况下进行两次递归调用(当L.head不是最小的时候):一次评估条件,第二次返回新值。这导致2 ^ n的复杂性。使用 temp 会保持线性。
答案 1 :(得分:1)
除了 loremIpsum1771 之外,我在这里给你一个简单的比喻:
for(int i=0; i< strlen(s); i++){
...
}
vs
for(int i=0, len=strlen(s); i<len; i++){
...
}
哪一个更快,为什么?
第一个慢得多,原因与您的OP完全相同,您每次/多次调用某些内容时确实可以预先计算一次