[英]Forming recurrence relations
我對形成遞歸關系和計算時間復雜度有疑問。
如果我們有遞歸關系T(n)= 2T(n / 2)+ c,那么這意味着在繪制遞歸時,恆定的功c被分為2個部分T(n / 2)+ T(n / 2)樹。
現在考慮階乘的遞歸關系T(n)= n * T(n-1)+ c。 如果遵循上述方法,則應將工作c分為每個T(n-1)的n個實例,然后評估時間復雜度。 但是,如果以此方式計算,則答案將為O(n ^ n),因為我們將進行O(n ^ n)個遞歸調用,這是錯誤的。
所以我的問題是為什么我們不能像第一種情況一樣使用將元素划分為子部分的方法。
令遞歸關系為T(n) = a * T(n/b) + O(n)
。
這種重復意味着存在一個遞歸函數,該遞歸函數:
a
子問題 n
,則每個子問題的大小將為n/b
當我們說原始問題分為a
子問題時,我們的意思是函數體內有a
遞歸調用。
因此,例如,如果函數是:
int f(int n)
{
if(n <= 1)
return n;
return f(n-1) + f(n-2);
}
我們說問題(大小為n
)分為兩個子問題,大小為n-1
和n-2
。 遞歸關系為T(n) = T(n-1) + T(n-2) + c
。 這是因為有2個遞歸調用,並且具有不同的參數。
但是,如果函數是這樣的:
int f(int n)
{
if(n <= 2)
return n;
return n * f(n-1);
}
我們說問題(大小為n
)僅分為1個子問題,大小為n-1
。 這是因為只有1個遞歸調用 。
因此,遞歸關系將為T(n) = T(n-1) + c
。
如果將T(n-1)
乘以n
,這似乎是正常現象,則表示正在進行n
遞歸調用。
請記住,我們形成遞歸關系的主要動機是對遞歸函數執行(漸近)復雜性分析。 即使看起來n
不能從關系中丟棄(因為它取決於輸入大小),它也不能起到與函數本身相同的作用。
但是,如果您正在談論函數返回的值 ,則將為f(n) = n * f(n-1)
。 在這里,我們將n
與相乘,因為它是一個實際值,將在計算中使用。
現在,來到c
在T(n) = T(n-1) + c
; 它只是表明,當我們解決大小的問題n
,我們需要解決規模較小的問題, n-1
和其他一些常數 (固定時間)工作等相比,乘法和還進行返回值。
即使使用遞歸樹方法,我們也永遠無法將“恆定工作量c
”分為T(n/2)
和T(n/2)
兩部分。 實際上,我們將問題分為兩半。 在遞歸樹的每個級別中的每個遞歸調用中,都需要相同數量的“ c
”工作。
如果存在類似T(n) = 2T(n/2) + O(n)
的遞歸關系,其中要完成的工作量取決於輸入大小,則每個級別上要完成的工作量將就像您描述的那樣,在下一個級別減少一半。
但是,如果遞歸關系像T(n) = T(n-1) + O(n)
,則在下一遞歸級別中,我們不會將工作量分為兩半。 我們只需要在每個后續級別將工作量減少一個即可( n
問題在下一級別變為n-1
)。
若要檢查工作量隨遞歸的變化,請將替代方法應用於遞歸關系。
我希望我已經回答了你的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.