劍指Offer對答如流系列 斐波那契數列

2022-08-30 02:33:13 字數 1681 閱讀 7643

寫乙個函式,輸入n,求斐波那契(fibonacci)數列的第n項。斐波那契數列的定義如下:

直接寫遞迴的話,是絕對ok的,但是你要明白乙個道理,凡是遞迴能夠完成的,遞推也能夠,而且效能還要優於遞迴,但是遞推寫起來總要難於遞迴。

對於斐波那契數列型別的習題,如果你要直接寫遞迴函式(通常的那種遞迴,後面會有優化),會出現比較多的重複計算,加之遞迴深度消耗的空間複雜度和時間複雜度代價是比較大的。

這裡遞推的寫法可以解決斐波那契數列遞迴寫法的弊端。

我們採用從下往上計算,把計算過了的值儲存起來,下次參與計算直接使用:先由f(0)和f(1)計算f(2),再由f(1)和f(2)計算f(3)……以此類推就行了,計算第n個時,只要儲存第n-1和第n-2項就可以了。

遞推解法:

public class fibonacci 

return result;}}

當然,如果你非常想用遞迴,但是又不想有那麼高的時間複雜度,有沒有辦法?有,當然有。線性代數中有這方面的討論。斐波那契數列有以下公式

根據公式,如果你想求f(n),只需要對矩陣求(n-1)次方即可,但此時時間複雜度仍為o(n)。利用遞迴的思路計算乘方,即可將時間複雜度降低為o(logn)。這裡給出對乘方函式的遞迴**

乘方的性質的性質如下

遞迴解答:

matrix2by2 matrixpower(unsigned int n)

else if(n % 2 == 0)

else if(n % 2 == 1)

return matrix;

}

數學學得好,有用嗎? 這道題的解答能證明吧。

斐波那契數列的變形有很多。

比如劍指offer後面的拓展:青蛙跳台階問題和矩形覆蓋問題,希望當你分析一些問題的時候,腦海裡有斐波那契數列的數學模型。

(1)拓展題目1:青蛙跳台階

乙隻青蛙一次可以跳上1級台階,也可以跳上2級。求該青蛙跳上乙個n級的台階總共有多少種跳法。

將跳法總數記為f(n)

f(1)=1

f(2)=2

當n>2時,第一次跳1級的話,還有f(n-1)種跳法;

當n>2時,第一次跳2級的話,還有f(n-2)種跳法

f(n)=f(n-1)+f(n-2)的遞推式能夠悟出來吧。

(2) 拓展題目2:矩形覆蓋問題

用n個21的小矩形無重疊地覆蓋乙個2n的大矩形,總共有多少種方法?

當n = 1時,有一種方法。

當n = 2時,有兩種方法。

當n >= 3時,和斐波那契數列類似。

第一步豎著放,有f(n-1)種方法;第一步橫著放,有f(n-2)種方法。所以f(n)=f(n-1)+f(n-2)。

除了斐波那契數列簡單直觀的數學模型,我們也應該加強一下科學歸納法的思想。

劍指Offer對答如流系列 醜數

我們把只包含質因子2 3和5的數稱作醜數 ugly number 求按從小到大的順序的第n個醜數。例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。判斷乙個數是不是醜數,最容易想到的方法就是讓這個數不斷除以2,3,5。對於第n個醜數,只要從1開始,依次判斷每個數是不...

劍指Offer對答如流系列 剪繩子

給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到最大的乘積18。遇到問題,先分析問題,由分析的結果確定所運用的演...

劍指Offer對答如流系列 包含min函式的棧

定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的min函式。在該棧中,呼叫min push及pop的時間複雜度都是o 1 push 和 pop均容易實現。主要就是min函式的定義,如果要通過操作push和pop操作獲取最小元素時間複雜度為o 1 基本上是不可能的。如果我們另外定義乙個成員...