【7】變態跳臺階

題目描述

一只青蛙一次可以跳上1級臺階,也可以跳上2級……它也可以跳上n級。求該青蛙跳上一個n級的臺階總共有多少種跳法。

我的想法

因為和斐波那契變種的跳臺階很像,首先想到的還是寫遞歸公式,看能不能推出什么。表面上有種f(n) = f(n-1) + f(n-2) + f(n-3) + ... + f(n - (n-1))的感覺,發現如果真的是這樣,完全可以化簡成f(n) = 2^(n-2) * f(1),但是這當然是錯的,細細一想就會發現會多出很多重復情況,這個式子完全不可取。
于是換一種思路,可以去選擇臺階,選擇跳上n階所踩過的臺階。于是得出這樣的式子,f(n) = 1 + C(1, n-1) + C(2, n-2) + ... + C(n-1, n-1),這很數學。列出階乘公式,帶入很容易就ac了。
代碼如下:

public class Solution {
    public int JumpFloorII(int target) {
        int rtn = 1;
        long njie = jiecheng(target - 1);
        for (int i = 1; i < target; i++) {
            rtn += njie / (jiecheng(i) * jiecheng(target - 1 - i));
        }
        return rtn;
    }

    public long jiecheng(int start) {
        long rtn = 1;
        for (int i = start; i >= 1; i--) {
            rtn *= i;
        }
        return rtn;
    }
}

別人的思路

看到解析第一個,又驚了,只有幾行代碼......思路和我的很不一樣,具體是這樣的:
f(1) = f(1-1) = 1
f(2) = f(2-1) + f(2-2) = f(1) + f(0)
f(3) = f(3-1) + f(3-2) + f(3-3) = f(2) + f(1) + f(0)
f(n) = f(n-1) + f(n-2) + ... + f(n-n) = f(0) + f(1) + f(2) + ... + f(n-1)
解釋一下就是當跳的臺階只有一階時,只有一種跳法。
當跳兩階臺階時,可以分兩種方式,直接跳上去,另一種是先跳一階,再跳上去,只是第二種方法跳過第一步后就變成跳一階的情況。
了。
同樣跳三階樓梯,分三種,1.先跳一階后轉換成f(2),2.先跳兩階轉換成f(1),3.直接跳上去。
這種思路就推出了上面的公式。化簡一下:
f(n-1) = f(0) + f(1) + f(2) + ... + f(n-2)
f(n) = (f(0) + f(1) + f(2) + ... + f(n-2)) + f(n-1) = 2*f(n-1)

推出來的公式真的超簡單啊,代碼就沒有什么難度了
f(n) = 2*f(n-1)。

public class Solution {
    public int JumpFloorII(int target) {
        if (target <= 1) {
            return 1;
        } else {
            return 2 * JumpFloorII(target - 1);
        }
    }
}

但是畢竟這是遞歸,來看幾個優化:
迭代:

class Solution {
    public int JumpFloorII(int target) {
        int rtn = 1;
        while (--target != 0) {
            rtn *= 2;
        }
        return rtn;
    }
}

位運算一行代碼:

class Solution {
    public int JumpFloorII(int target) {
        return 1<<(target-1);
    }
}

可怕可怕,移位代替了乘2的工作,運算速度更快。
感覺自己想到方法已經很不容易了,看到別人的算法,感覺思維好有差距,還是要多練多練。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容