【劍指Offer】變態跳臺階
阿新 • • 發佈:2019-05-04
快速 原來 return 斐波那契數 count csdn n) title article
青蛙第一次可以跳1級,則還剩n - 1級臺階,即F(n - 1)
青蛙第一次可以跳2級,則還剩n - 2級臺階,即F(n - 2)
...
青蛙第一次可以跳n - 1級,則還剩1級臺階,即F(1)
青蛙第一次可以跳n級,即1種跳法
則F(n) = F(n - 1) + F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1
很顯然F(1)= 1,在已知F(1)的情況下,我們可以利用遞歸解這道題,代碼如下
...
不難發現,對於n級臺階,總跳法數是2^n-1^
當然我們也可以通過公式推導出這個結果
由解法1可知
F(n) = F(n - 1) + F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1,則
F(n - 1) = F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1
兩個式子合並可得F(n) = 2F(n - 1),則
F(n - 1) = 2F(n - 2)
F(n - 2) = 2F(n - 3)
即F(n) = 2^2^F(n - 2),F(n) = 2^3^F(n - 3)
以此類推,F(n)= 2^n-1^F(n - (n - 1)) = 2^n-1^F(1) = 2^n-1^
最終這道題被轉換成如何求解2^n-1^,簡單的方法是對2連乘n-1次,繼續優化的話,可以使用整數的快速冪,【劍指Offer】斐波那契數列也已經有了詳細的詳解。下面僅放上本題的整數快速冪解法
目錄
- 題目描述
- 解法1
- 實現代碼
- 解法2
- 實現代碼
- 解法3
- 實現代碼
題目描述
一只青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。
解法1
本題是【劍指Offer】跳臺階的進化版本。
原來的青蛙只可以跳上1級或2級,即F(n) = F(n - 1) + F(n - 2)
現在的青蛙可以跳上1到n的任意級,按照之前的解題思路,依然先來看F(n),對於一個n級臺階來說
青蛙第一次可以跳2級,則還剩n - 2級臺階,即F(n - 2)
...
青蛙第一次可以跳n - 1級,則還剩1級臺階,即F(1)
青蛙第一次可以跳n級,即1種跳法
則F(n) = F(n - 1) + F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1
很顯然F(1)= 1,在已知F(1)的情況下,我們可以利用遞歸解這道題,代碼如下
實現代碼
public int jumpFloorII(int number) { int count = 1; for (int i = 1; i < number; i++) { count = count + jumpFloorII(number - i); } return count; }
解法2
本題的遞歸算法由於編譯器的低效實現不可避免的會存在大量的重復運算,我們可以在遞歸的基礎上做一些優化,詳細說明可以查看【劍指Offer】斐波那契數列。或者換一種思路,我們也可以不使用遞歸。有時候列出結果的前幾項,找找規律,可能會有意想不到的收獲
對於1級臺階,青蛙只有1 = 2^0^種跳法
對於2級臺階,青蛙有2 = 2^1^種跳法(分別是{1,1}, {2})
對於3級臺階,青蛙有4 = 2^2^種跳法(分別是{1,1,1}, {1,2}, {2,1}, {3})
對於4級臺階,青蛙有8 = 2^3^種跳法(分別是{1,1,1,1}, {1,1,2}, {1,2,1}, {2,1,1}, {2,2}, {1,3}, {3,1}, {4})
不難發現,對於n級臺階,總跳法數是2^n-1^
當然我們也可以通過公式推導出這個結果
由解法1可知
F(n) = F(n - 1) + F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1,則
F(n - 1) = F(n - 2) + F(n - 3) + F(n - 4) + ... + F(1) + 1
兩個式子合並可得F(n) = 2F(n - 1),則
F(n - 1) = 2F(n - 2)
F(n - 2) = 2F(n - 3)
即F(n) = 2^2^F(n - 2),F(n) = 2^3^F(n - 3)
以此類推,F(n)= 2^n-1^F(n - (n - 1)) = 2^n-1^F(1) = 2^n-1^
最終這道題被轉換成如何求解2^n-1^,簡單的方法是對2連乘n-1次,繼續優化的話,可以使用整數的快速冪,【劍指Offer】斐波那契數列也已經有了詳細的詳解。下面僅放上本題的整數快速冪解法
實現代碼
public int jumpFloorII(int number)
{
number = number - 1;
int count = 1;
int m = 2;
while (number > 0)
{
if ((number & 1) > 0)
{
count *= m;
}
m = m * m;
number = number >> 1;
}
return count;
}
解法3
對於求解2^n-1^,可以繼續優化,利用左移運算,只使用一行代碼就可以得到2^n-1^
對於數字1,左移1位是10,即2 = 2^1^
左移2位是100,即4 = 2^2^
左移3位是1000,即8 = 2^3^
以此類推,左移n位,就是2^n^
要求2^n-1^,只需要將數字1左移n-1位,對應的代碼如下
實現代碼
public int jumpFloorII(int number)
{
return 1 << (number - 1);
}
【劍指Offer】變態跳臺階