LeetCode算法題-Climbing Stairs(Java實(shí)現(xiàn))

這是悅樂書的第159次更新,第161篇原創(chuàng)


01 看題和準(zhǔn)備

今天介紹的是LeetCode算法題中Easy級別的第18題(順位題號是70)。你正在爬樓梯,它需要n步才能達(dá)到頂峰。每次你可以爬1或2步,你可以通過多少不同的方式登頂?注意:給定n是一個(gè)正整數(shù)。例如:

輸入:2
輸出:2

說明:有兩種方法可以爬到頂端

1、1步 + 1步

2、2步

輸入:3
輸出:3

說明:有三種方法可以爬到頂端

1、1步 + 1步 + 1步

2、1步 + 2步

3、2步 + 1步

輸入:4
輸出:5

說明:有5種方法可以爬到頂端

1、1步 + 1步 + 1步 + 1步

2、1步 + 1步 + 2步

3、1步 + 2步 + 1步

4、2步 + 1步 + 1步

5、2步 + 2步

本次解題使用的開發(fā)工具是eclipse,jdk使用的版本是1.8,環(huán)境是win7 64位系統(tǒng),使用Java語言編寫和測試。


02 第一種解法

關(guān)于題目,可以從簡單的條件開始推導(dǎo)。

當(dāng)n等于1的時(shí)候,有1種方式。

當(dāng)n等于2的時(shí)候,有2種方式。

當(dāng)n等于3的時(shí)候,有3種方式。

當(dāng)n等于4的時(shí)候,有5種方式。

當(dāng)n等于5的時(shí)候,有8種方式。

看到這,你會(huì)發(fā)現(xiàn)從n等于2開始,后一項(xiàng)等于前兩項(xiàng)的和,這時(shí)很容易想到遞歸,于是就有了第一種解法。

public int climbStairs(int n) {
    if (n == 1) {
        return 1;
    }
    if (n == 2) {
        return 2;
    }
    return climbStairs(n-1) + climbStairs(n-2);
}


03 第二種解法

上面的解法,你應(yīng)該也發(fā)現(xiàn)問題了,運(yùn)行太慢了。有什么可以優(yōu)化的呢?既然只是求前兩個(gè)數(shù)的和,那么可以引用數(shù)組來存值,而不是每次都來重新算一次。

public int climbStairs2(int n) {
    int[] arr = new int[n+1];
    return climb(n, arr);
}

public int climb(int n, int[] arr){
    if (n == 0 || n == 1) {
        return 1;
    } else if(arr[n] > 0) {
        return arr[n];
    }
    arr[n] = climb(n-1, arr) + climb(n-2, arr);
    return arr[n];
}

在climb方法里判斷里,是要加上else if那個(gè)判斷的,目的是避免重復(fù)計(jì)算,不判斷的話就和第一種差不多了。


04 第三種解法

既然利用數(shù)組來存值,那么是不是可以省掉遞歸?直接拿數(shù)組元素返回結(jié)果就行。

public int climbStairs3(int n) {
    int[] arr = new int[n+1];
    arr[0] = 1;
    arr[1] = 1;
    for (int i=2; i<arr.length; i++) {
        arr[i] = arr[i-1]+arr[i-2];
    }
    return arr[n];
}


05 三種解法對比

為了驗(yàn)證哪種解法花費(fèi)的時(shí)間更少,編寫了一些簡易的測試代碼。

public static void main(String[] args) {
    Easy_070_ClimbingStairs instance = new Easy_070_ClimbingStairs();
    int arg = 44;
    long start = System.nanoTime();
    int result = instance.climbStairs(arg);
    long end = System.nanoTime();
    System.out.println("climbStairs---輸入:"+arg+" , 輸出:"+result+" , 用時(shí):"+(end-start)/1000+"微秒");
    System.out.println("----------------------------");
    long start2 = System.nanoTime();
    int result2 = instance.climbStairs2(arg);
    long end2 = System.nanoTime();
    System.out.println("climbStairs2---輸入:"+arg+" , 輸出:"+result2+" , 用時(shí):"+(end2-start2)/1000+"微秒");
    System.out.println("----------------------------");
    long start3 = System.nanoTime();
    int result3 = instance.climbStairs3(arg);
    long end3 = System.nanoTime();
    System.out.println("climbStairs3---輸入:"+arg+" , 輸出:"+result3+" , 用時(shí):"+(end3-start3)/1000+"微秒");
}

下面是運(yùn)行的結(jié)果

climbStairs---輸入:44 , 輸出:1134903170 , 用時(shí):2795896微秒
----------------------------
climbStairs2---輸入:44 , 輸出:1134903170 , 用時(shí):9微秒
----------------------------
climbStairs3---輸入:44 , 輸出:1134903170 , 用時(shí):6微秒

可以看出來,第三種解法是最優(yōu)的,遞歸是好算法,但是會(huì)造成很多重復(fù)計(jì)算,影響速度,需要分場景來使用遞歸算法。


06 小結(jié)

以上就是全部內(nèi)容,如果大家有什么好的解法思路、建議或者其他問題,可以下方留言交流,點(diǎn)贊、留言、轉(zhuǎn)發(fā)就是對我最大的回報(bào)和支持!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 一、CustomKeyboardView :顯示的鍵盤view二、keyModel:鍵盤model,定義鍵盤字母枚...
    煙雨痕閱讀 2,057評論 3 1
  • ——用戶今天所需要的,明天可能不需要;用戶明天所需要的,今天可能不需要。 我曾經(jīng)了解到,像Google、Faceb...
    樹欲靜閱讀 295評論 0 0
  • 如今生活的步調(diào)太快,轉(zhuǎn)眼之間,明天孩子就要參加期末考試了。 今天,孩子休息,其他年級的學(xué)生考試...
    寧寶讀書吧閱讀 328評論 0 0
  • 想了良久,醞釀良久,總覺得還是將最近一周寫下來,不算傾訴,算是對生活的一種記錄。 我很久沒有那種憋的不行的感覺了,...
    景桑閱讀 1,203評論 2 2

友情鏈接更多精彩內(nèi)容