如果我們需要重複地多次計算相同的問題,則通常可以選擇用遞迴或者迴圈兩種不同的方法。
遞迴是在乙個函式的內部呼叫這個函式自身。而迴圈則是通過設定計算的初始值及終止條件,在乙個範圍內重複運算。
通常遞迴的**會比較簡潔。但是它同時也有顯著的缺點。遞迴由於是函式呼叫自身,而函式呼叫是有時間和空間的消耗的:每一次函式呼叫,都需要在記憶體棧中分配空間以儲存引數、返回位址、臨時變數,而且往棧裡壓如資料和彈出資料都需要時間。
另外,遞迴中有可能很多計算都是重複的,從而對效能帶來很大的負面影響。遞迴的本質是把乙個問題分解成兩個或者多個小問題。如果多個小問題存在相互重疊的部分,就存在重複的計算。
通常應用動態規劃解決問題時我們都是用遞迴的思路分析問題,但由於遞迴分解的子問題中存在大量的重複,因此我們總是用自下而上的迴圈來實現**。
除效率之外,遞迴還有可能引起更嚴重的問題:呼叫棧溢位。在前面的分析中提到需要為每一次函式呼叫在記憶體棧中分配空間,而每個程序的棧的容量是優先的。當遞迴呼叫的層級太多,就會超出棧的容量,從而導致呼叫棧溢位。
class
solution
if(n==
0||n==1)
for(
int i=
2;i<=n;i++
)return b;}}
;
時間複雜度是o(n
)o(n)
o(n)
。時間複雜度o(l
ogn)
o(logn)
o(logn
),但不夠實用的解法
用到如下公式:
比較複雜,不再贅述。
思路:第n級台階的跳法就是:從第n-1級台階跳1級,從第n-2級台階跳2級。因此第n級台階的跳法就是第n-1級台階的跳法加第n-2級台階的跳法。
和斐波那契數列的思想是一樣的。
class
solution
if(n==
1||n==0)
for(
int i=
2;i<=n;i++
)return b;}}
;
相關題目
遞迴和迴圈
從功能上來說,所有用遞迴實現的都可以用迴圈實現,只不過有時候遞迴實現方便一些,從效率上說,迴圈一般都是大於遞迴的。如果要處理的問題的深度不大,我認為遞迴和迭代的效率差不多。遞迴是消費棧空間,先遞推 壓棧 然後回歸 逐步釋放占用的棧 如果遞迴的深度比較大的話會很消耗記憶體,如果沒有終止條件會導致棧溢位...
遞迴和迴圈
很早之前看到過一段關於遞迴的解釋覺得很nice 今天寫了四道關於遞迴迴圈的題 大家都知道斐波那契數列,現在要求輸入乙個整數n,請你輸出斐波那契數列的第n項。n 39 f n f n 1 f n 2 第一眼看就是遞迴啊,簡直完美的遞迴環境,遞迴肯定很爽,這樣想著關鍵 兩三行就搞定了,注意這題的n是從0...
迴圈和遞迴
改為遞迴的關鍵是發現邏輯的 相似性 不要忘記遞迴的 出口 例子 使用遞迴模擬迴圈 列印0到9 public staitc void main string args 修改 列印0 n public static void f int n 接下來我們實現公升序的遞迴,比如列印0到9,這裡為了更一般化,...