這兩種方法都是正確的。從一個函數中進行多次遞歸調用確實是合法的,其意義就是你想的 - 只需要一個調用,然後是下一個,然後是下一個等。
有趣的是,我不認爲遞歸版本確實使指數級的多次調用成爲可能。它最多可以進行兩次遞歸調用,但每個調用都會遇到一個問題,其大小約爲原始調用的一半。從本質上講,復發看起來是這樣的:
T(1) = 1
T(2) = 1
T(n) <= T(n/2) + T(n/2 + 1) + 1
我使用「小於或等於這裏」說,在最好的情況下,你可能只是做出一個電話,但在最壞的情況下,你讓最多兩個。
我想證明一些常數c,d和a的函數T(n)< = max {cn + d,a}。這將證明T(n)= O(n)並因此使得最多線性地多次調用。由於我們的基本情況,我們有
T(1) = 1
T(2) = 1
所以讓我們設置一個= 1。對於歸納步,我們考慮三種情況。首先,讓我們時地板(N/2)< = 2和地板(N/2 + 1)< = 2的考慮:
T(n) <= T(n/2) + T(n/2 + 1) + 1
<= 1 + 1 + 1
<= 3
如果我們假設CN + d> = 3,當n = 3或n = 4,那麼這個解決正確。尤其是,這意味着3c + d> = 3和4c + d> = 3。
在下一個案例中,讓我們看看樓層(n/2)< = 2和floor(n/2 + 1)> = 2。然後,我們有
T(n) <= T(n/2) + T(n/2 + 1) + 1
<= 1 + max{c(n/2 + 1) + d, 1} + 1
<= 2 + max{c(n/2 + 1) + d, 1}
<= 3 + c(n/2 + 1) + d
因此,如果我們有一個3 + C(N/2 + 1)+ d < = CN + d,這要求仍然成立。請注意,我們只能是在這種情況下,如果n = 5,所以這意味着我們必須有
3 + c(n/2 + 1) + d <= cn + d
3 + c(n/2 + 1) <= cn
3 + c(5/2 + 1) <= 5c
3 + 5c/2 + c <= 5c
3 + 7c/2 <= 5c
4 <= 3c/2
8/3 <= c
因此,我們必須有C> = 8/3
最後,情況下既沒有N/2也不N/2 + 1是少於三個:
T(n) <= T(n/2) + T(n/2 + 1) + 1
<= c(n/2) + d + c(n/2 + 1) + d + 1
<= cn/2 + cn/2 + c + 2d + 1
= cn + c + 2d + 1
這是小於CN + d如果
cn + c + 2d + 1 <= cn + d
c + 2d + 1 <= d
c + d + 1 <= 0
這WOR ks if d = -c - 1.
從前面我們知道3c + d> = 3,如果2c-1> = 3,或者2c> = 4,那麼c> = 2。有圖4c + d> = 3,如果c> = 2讓C = 8/3,我們得到這也適用的是d = -11/3,所以
T(n) <= max{8n/3 - 11/3, 1}
所以T(n)的= O (n)並且遞歸只能線性地處理很多調用。
這個簡短的版本是,遞歸和迭代版本都需要線性時間。不要擔心遞歸的指數時間爆炸而不確定它是指數的。 :-)雖然承認,在這種情況下,我更喜歡迭代版本。它更清晰,更直觀,更立即O(n)。
`高清鈣(N): IF ... ELSE: 回報計算的(N/2)+計算值(N/2 + 1)`不是嵌套的,只是重複。試試[Ackermann](https://en.wikipedia.org/wiki/Ackermann_function)。 – greybeard 2017-11-04 10:28:43