【劍指Offer】變態跳臺階

題目描述

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

解法1

本題是【劍指Offer】跳臺階的進化版本。
原來的青蛙只能夠跳上1級或2級,即F(n) = F(n - 1) + F(n - 2)
如今的青蛙能夠跳上1到n的任意級,按照以前的解題思路,依然先來看F(n),對於一個n級臺階來講
青蛙第一次能夠跳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)的狀況下,咱們能夠利用遞歸解這道題,代碼以下優化

實現代碼

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】斐波那契數列也已經有了詳細的詳解。下面僅放上本題的整數快速冪解法.net

實現代碼

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位,對應的代碼以下code

實現代碼

public int jumpFloorII(int number)
{
    return 1 << (number - 1);
}
相關文章
相關標籤/搜索