leetcode70題 爬樓梯

2021-10-23 02:32:54 字數 3000 閱讀 2097

每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?

注意:給定 n 是乙個正整數。

示例 1:

輸入: 2

輸出: 2

解釋: 有兩種方法可以爬到樓頂。

1 階 + 1 階

2 階示例 2:

輸入: 3

輸出: 3

解釋: 有三種方法可以爬到樓頂。

3. 1 階 + 1 階 + 1 階

4. 1 階 + 2 階

5. 2 階 + 1 階

方法一:暴力遞迴

演算法

第n階可以由以下兩種方法得到:

在第 (n-1)階後向上爬1階。

在第 (n-2)階後向上爬 2 階。

所以到達第 n 階的方法總數就是到第 (n-1)階和第 (n-2) 階的方法數之和。

不難得到遞迴公式:

f(n)=f(n-1)+f(n-2): 觀察發現相當於斐波那契數列(0,1,1,2,3,5,8,…)左移兩個單位。

遞迴實現

public  int climbstairs(int n)
複雜度分析

時間複雜度:o(2^n),

樹形遞迴的大小為 2^n 。

空間複雜度:o(n),遞迴樹的深度可以達到 n 。

方法二:記憶化(memoization)遞迴

演算法

在上一種方法中,我們計算每一步的結果時出現了冗餘。另一種思路是,我們可以把每一步的結果儲存在 memo陣列之中,每當函式再次被呼叫,我們就直接從 memo陣列返回結果。

在 memo 陣列的幫助下,我們得到了乙個修復的遞迴樹,其大小減少到 n。

實現在程式的入口處增加對全域性**的查詢,只有**沒有有效結果的時候進行實質性的計算。

public int climbstairs1(int n) 

if (memo[n] > 0)

memo[n] = climbstairs(n-1) + climbstairs(n-2);

return memo[n];

}

複雜度分析時間複雜度:o(n),樹形遞迴的大小可以達到 n。

空間複雜度:o(n),遞迴樹的深度可以達到 n。

方法三:動態規劃(dynamic programing)

演算法一般要麼是遞迴要麼是迭代,遞迴:自頂向下遞迴,迭代:自底向上迭代。此方法也是迭代。

遞迴:設計出可行且正確的解。動態規劃:消除重複計算,提高效率。

演算法

不難發現,這個問題可以被分解為一些包含最優子結構的子問題,即它的最優解可以從其子問題的最優解來有效地構建,我們可以使用動態規劃來解決這一問題。

第 i 階可以由以下兩種方法得到:

在第 (i−1) 階後向上爬1階。

在第 (i−2) 階後向上爬 2 階。

所以到達第 i階的方法總數就是到第 (i-1) 階和第 (i-2) 階的方法數之和。

令 dp[i] 表示能到達第 i 階的方法總數:

dp[i]=dp[i-1]+dp[i-2]

實現

public int climbstairs2(int n) 

int dp = new int[n+1];

dp[1] = 1;

dp[2] = 2;

for (int i=3; i<=n; i++)

return dp[n];

}

複雜度分析時間複雜度:o(n),單迴圈到 n 。

空間複雜度:o(n),dp陣列用了 n 的空間。

方法四:斐波那契數

演算法

在上述方法中,我們使用 dp 陣列,其中 dp[i]=dp[i-1]+dp[i-2]。可以很容易通過分析得出 dp[i] 其實就是第 i 個斐波那契數。

fib(n)=fib(n-1)+fib(n-2)

現在我們必須找出以 1 和 2 作為第一項和第二項的斐波那契數列中的第 n 個數,也就是說 fib(1)=1 且 fib(2)=2。

public int climbstairs3(int n) 

int first = 1;

int second = 2;

for (int i=3; i<=n;i++)

return second;

}

或者

public int climbstairs5(int n) 

int f = 0;

int g = 1;

while (1 < n)

return g;

}

複雜度分析

時間複雜度:o(n),單迴圈到 n,需要計算第 n 個斐波那契數。

空間複雜度:o(1),使用常量級空間(3個變數或者兩個)。

附:三步問題。有個小孩正在上樓梯,樓梯有n階台階,小孩一次可以上1階、2階或3階。實現一種方法,計算小孩有多少種上樓梯的方式。結果可能很大,你需要對結果模1000000007。

動態規劃寫法:只要遇到加法就取模,因為兩個太大數相加的話會溢位。

public int waystostep(int n) 

if (n <= 2)

int memo = new int[n+1];

memo[0] = 1;

memo[1] = 1;

memo[2] = 2;

for (int i=3;i<=n;i++)

return memo[n];

}

LeetCode 70 爬樓梯 簡單

假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2 輸出 2 解釋 有兩種方法可以爬到樓頂。1.1 階 1 階 2.2 階 示例 2 輸入 3 輸出 3 解釋 有三種方法可以爬到樓頂。1...

leetcode 70 爬樓梯 go實現

package main import fmt func main 斐波那契數列 前乙個數等於前兩個數之和 可以想,走到第i級台階有幾種方法呢,2種。1.從i 1級走一步到n級 2.從i 2級走兩步到n級 那也就是說,走到第i級台階的走法有f i f i 1 f i 2 也就是用第i 1級台階的走法...

C 練習 LeetCode 70 爬樓梯

假設你正在爬樓梯。需要 n 階你才能到達樓頂。每次你可以爬 1 或 2 個台階。你有多少種不同的方法可以爬到樓頂呢?注意 給定 n 是乙個正整數。示例 1 輸入 2 輸出 2 解釋 有兩種方法可以爬到樓頂。1 階 1 階 2 階示例 2 輸入 3 輸出 3 解釋 有三種方法可以爬到樓頂。1 階 1 ...