寫在前面
最近參加了算法訓練營,參與了每日一道算法題的挑戰,準備寫完算法題,再更新一份學習了該算法題後的心得。如果有刷題需要的可以看下,題目來源是LeetCode,也可以自行去搜索。本人上班黨,如果有時間,可能會再更新些其他的學習心得。
題目
假設你正在爬樓梯。需要 n 階你才能到達樓頂。
每次你可以爬 1 或 2 個臺階。你有多少種不同的方法可以爬到樓頂呢?
注意:給定 n 是一個正整數。
示例1
n=2
輸出2
解釋:有兩種方法可以爬到樓梯
- 1階+1階
- 2階
示例2
n = 3
輸出3
解釋:有三種方法可以爬到樓梯
- 1階+1階+1階
- 1階+2階
- 2階+3階
示例3
n = 4
輸出5
解釋:有五種方法可以爬到樓梯
- 1+1+1+1
- 1+1+2
- 1+2+1
- 2+1+1
- 2+2
解法:動態規劃
從上面的示例,可以發現第i階可以由第(i-1)階 和第(i-2)階得到
1.第i階,可以在第(i-1)階後,向上爬一階
2.第i階,可以在第(i-2)階後,向上爬兩階
所以 打到第i階的方法總數就是到達第(i-1)的方法數+到達第(i-2)階的方法數
i = (i-1)+ (i-2)
代碼示例
class Solution {
public int climbStairs(int n) {
if(n == 1){
return 1;
}
if(n == 2){
return 2;
}
int[] dp = new int[n+1];
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
時間複雜度:O(n) 單循環n次
空間複雜度:O(n) 利用長度爲n+1的數組來存儲到達第i階的方法數
斐波那契數列
class Solution {
public int climbStairs(int n) {
// 很顯然,只有1階時,只有1種方法
if(n == 1){
return 1;
}
// 很顯然,只有2階時,只有2種方法
if(n == 2){
return 2;
}
int first = 1;
int second = 2;
int sum = 0;
for(int i = 3; i <= n; i++){
sum = first + second;
first = second;
second = sum;
}
return sum;
}
}
時間複雜度:O(n) 單循環n次
空間複雜度:O(1) first,second,sum三個變量存儲數據,佔用了常量級空間