LeetCode 70題 爬樓梯 -- JavaScript

Jealyn發表於2018-08-15

題目描述:

假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?

注意給定 n 是一個正整數

示例 :

輸入: 2
輸出: 2
解釋: 有兩種方法可以爬到樓頂。
1.  1 階 + 1 階
2.  2 階
輸入: 3
輸出: 3
解釋: 有三種方法可以爬到樓頂。
1.  1 階 + 1 階 + 1 階
2.  1 階 + 2 階
3.  2 階 + 1 階

方法分析: 

這道題主要是要明白該爬樓梯的規律其實就是符合斐波那契數列(Fibonacci Sequence) 規律的,問題就迎刃而解了。為什麼說它是斐波那契數列呢?我們可以這樣來思考:當我們從第 n-1 階樓梯爬到第 n 階樓梯時,需要1步;當我們從第 n-2 階樓梯爬到第 n 階樓梯時,需要2步.也就是說 到達第 n 階樓梯的方法數等於到達第 n-1 階樓梯的方法數加上到達第 n-2 階樓梯的方法數,即 \small {\color{Red} f(n) = f(n - 1) + f(n - 2)},其正好符合斐波那契通項。

程式碼實現:

1. 採用遞迴實現

var climbStairs = function(n) {
    if(n == 1) return 1;
    if(n == 2) return 2;
    return climbStairs(n-1) + climbStairs(n-2);
};

遞迴是求解斐波那契數列最經典和最直接的方式,其簡潔易懂;但是遞迴特別費時,在該題中使用會出現超出時間限制的錯誤提示。

2. 陣列方式

var climbStairs = function(n) {
    let result = [1,2];
    for (let i = 2; i < n; i++) {
        result.push(result[i-1] + result[i-2]);
    }
    return result[n-1];
};

陣列方式大大的減少了執行時間,因為從第三項開始 \small {\color{Red} f(n) = f(n - 1) + f(n - 2)} ,所以我們先預設好前兩項,再得到結果,返回陣列最後一項即可。

3. ES6的方式

var climbStairs = function(n) {
    let a = b = 1;
    for (let i = 0; i < n; i++) {
        [a, b] = [b, a + b];
    }
    return a;
};

其中 [a, b] = [b, a + b] 表示解構賦值,其等價於

temp = a;
a = b;
b = temp + b;

程式碼解析:

本文給出了三種解法,其中第一種解法主要是丟擲思路,在LeetCode上提交是不會成功的;第二種和第三種方法都利用了陣列的知識,方法二較為明瞭,方法三通過解構賦值給出了另一種思路。

相關連結:https://leetcode-cn.com/problems/climbing-stairs/description/

相關文章