標籤:數學 遞迴 青蛙跳台階 劍指offer 演算法
題目:一隻青蛙一次可以跳上 1 級台階,也可以跳上2 級。求該青蛙跳上一個n 級的台階總共有多少種跳法。
我的思路:最開始我的思路是把這個看成是一個數學問題,n=i*1+k*2先把所有可能滿足這個公式的i和k求出來。然後在對i和k做排列組合。很明顯i的範圍應該是0<i<=n,所以我們已i開始迭代。下面貼上代碼吧。把注釋都寫上!
public int JumpFloor(int target) {int step = 0;for (int i = 0; i <= target; i++) {if (0 == (target - i) % 2) {// 只要滿足這個條件就是符合的組合// 只要能夠符合的都是可以的情況// I代表的是跳一步的次數,如果I=0或者I=target這不可能出現多種排列的情況if (i == 0 || i == target) {step++;// 只有一種排列情況,要麼全是1,要麼全是2} else {/* * 出現全排列的情況。利用排列組合的思想算出這一次有多少種走法 */int oneNum = i;// 為1的有i個int twoNums = (target - i) / 2;// 為2的有這麼多個/** * 全排列個數AII/AKK*AJJ(i表示中共的1和2的個數,k表示1的個數, * j表示2的個數,simpleCircle是 算一個數的階乘) */int stepCount = simpleCircle(oneNum + twoNums)/ (simpleCircle(oneNum) * simpleCircle(twoNums));step += stepCount;}}}return step;}public int simpleCircle(int num) {// 簡單的迴圈計算的階乘int sum = 1;if (num < 0) {// 判斷傳入數是否為負數throw new IllegalArgumentException("必須為正整數!");// 拋出不合理參數異常}for (int i = 1; i <= num; i++) {// 迴圈numsum *= i;// 每迴圈一次進行乘法運算}return sum;// 返回階乘的值}
小結:筆者這個解法雖然感覺思路比較清晰,但是感覺不是很巧妙!(其實數字算出來你會發現其實是一個fibo數列)沒有亮點,但是這種解法當2變成其他數的時候是通用的
下面我們來看看網上大家的解法(這是一道劍指offer上面的題目),首先是結合Fibonacci數列來解決問題
分析:1)當n = 1, 只有1中跳法;當n = 2時,有兩種跳法;當n = 3 時,有3種跳法;當n = 4時,有5種跳法;當n = 5時,有8種跳法;.......
規律類似於Fibonacci數列
2)
如果n=1,總步數f(n)=1;如果n=2,總步數f(n)=2。
另一方面,當n>=3,當前還剩的步數f(n),如果接下去跳一步,那麼還剩下的步數是f(n-1);如果接下去跳兩步,那麼還剩下的步數是f(n-2),故:f(n)=f(n-1)+f(n-2)。
int Fib(int n){//典型的fibo數列方法if (n <= 0){cout << "error!" << endl;return -1;}if (1 == n){return 1;}else if (2 == n){return 2;}else{return Fib(n - 1) + Fib(n - 2);}}
-----------------------------------------------分割線-------------------------------------------------------------------------------
下面是這道題的變化題目,非常不錯!
問:一隻青蛙一次可以跳上1級台階,也可以跳上2 級……它也可以跳上n 級,此時該青蛙跳上一個n級的台階總共有多少種跳法?
用Fib(n)表示青蛙跳上n階台階的跳法數,青蛙一次性跳上n階台階的跳法數1(n階跳),設定Fib(0) = 1;
當n = 1 時, 只有一種跳法,即1階跳:Fib(1) = 1;
當n = 2 時, 有兩種跳的方式,一階跳和二階跳:Fib(2) = Fib(1) + Fib(0) = 2;
當n = 3 時,有三種跳的方式,第一次跳出一階後,後面還有Fib(3-1)中跳法; 第一次跳出二階後,後面還有Fib(3-2)中跳法;第一次跳出三階後,後面還有Fib(3-3)中跳法
Fib(3) = Fib(2) + Fib(1)+Fib(0)=4;
當n = n 時,共有n種跳的方式,第一次跳出一階後,後面還有Fib(n-1)中跳法; 第一次跳出二階後,後面還有Fib(n-2)中跳法..........................第一次跳出n階後, 後面還有 Fib(n-n)中跳法.
Fib(n) = Fib(n-1)+Fib(n-2)+Fib(n-3)+..........+Fib(n-n)=Fib(0)+Fib(1)+Fib(2)+.......+Fib(n-1)
又因為Fib(n-1)=Fib(0)+Fib(1)+Fib(2)+.......+Fib(n-2)
兩式相減得:Fib(n)-Fib(n-1)=Fib(n-1) =====》 Fib(n) = 2*Fib(n-1) n >= 2
遞迴等式如下:
】
代碼特簡單,但是分析就不是這麼簡單的事情了:
public int jumpN(int n) {if (n == 0 || n == 1) {return 1;}return 2 * jumpN(n - 1);}
其他想法目前還沒有想出來,先貼著吧。
轉載請註明http://blog.csdn.net/a837199685
青蛙跳台階問題