劍指offer--變態跳臺階
阿新 • • 發佈:2018-12-14
題目如下:
一隻青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
解題思路:
其實有兩種解題思路,個人更傾向於第二種方法,應為個人覺得它更符合計算機解決問題的思路。
在這道題目之前,其實還有一個簡單的青蛙跳臺階,就是青蛙可以跳一次和跳兩次,這個其實很簡單也沒啥好說的,使用遞迴就可以得到我們想要的結果。
我們看看這道題,我一開始的想法也是使用遞迴,最後發現其實還是那麼回事。。。
思路一:
假設 青蛙跳到n級的方法是 F(n) 那麼F(n)是怎麼來的呢?我們從後往前思考 1.青蛙跳到第n-1級,最後跳1步 ,而跳到n-1級的跳法是F(n-1) A1 = F(n-1) 2.青蛙跳到第n-2級,最後跳2步 ,而跳到n-2級的跳法是F(n-2) A2 = F(n-2) ..... n-1.青蛙跳到第1級,最後跳n-1步 ,而跳到1級的跳法是F(1) An-1 = F(1) n. 青蛙直接跳n級,An = 1
那麼我麼可以得到如下結果:
a. F(n) = A1 + A2 + …+ An-1 + An = F(n-1) + F(n-2) + … + F(1) + 1
b. F(n-1) = F(n-2) + … + F(1) + 1
c. F(n) = F(n-1) + F(n-1) = 2F(n-1)
所以結果就很簡單了
function jumpFloorII(number) { if( number === 1){ return 1; }else{ return 2 * jumpFloorII(number - 1); } }
所以這道題究竟是演算法呢還是數學呢?。。。。
思路二:
這個方法是我檢視其他解法時發現的,本質和思路一差不多,不同的地方在於它並沒有上文中的推理步驟b和c,僅僅是依靠公式a就得到的最終的結果,下面讓我們一起看看程式碼
function jumpFloorII(number) { if(number === 1){ return 1; }else if( number > 1){ //建立一個空陣列,用來儲存對應每一個小於number的n的跳法結果 let arr = new Array(number + 1).fill(0); arr[0] = 0; arr[1] = 1; for(let i = 2; i <= number; i++ ){ // An = An-1 + An-2 + ... + A1 + 1 for( let j = 1 ; j < i ; j++ ){ arr[i] += arr[j]; } arr[i] += 1; } return arr[number]; }else{ return -1; } }
巧妙的使用陣列,將每一次的An-1計算結果儲存起來,而後面的An的計算結果是依賴前面的A1…An-1的。