写在前面
最近参加了算法训练营,参与了每日一道算法题的挑战,准备写完算法题,再更新一份学习了该算法题后的心得。如果有刷题需要的可以看下,题目来源是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三个变量存储数据,占用了常量级空间