一.题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
注意:给定 n 是一个正整数。
示例 1:
输入: 2 输出: 2 解释: 有两种方法可以爬到楼顶。
- 1 阶 + 1 阶
- 2 阶
示例 2:
输入: 3 输出: 3 解释: 有三种方法可以爬到楼顶。
- 1 阶 + 1 阶 + 1 阶
- 1 阶 + 2 阶
- 2 阶 + 1 阶
二.题目解析
1.递归
public int climbStairs1(int n) {
/*递归
* */
if(n == 0 || n == 1){
return 1;
}
return climbStairs1(n - 1) + climbStairs1(n - 2);
}
2.记忆化递归
public int climbStairs(int n) {
/*记忆化递归
* */
int[] memo = new int[n + 1];
//数组初始化
Arrays.fill(memo,-1);
return findByRecursion(n,memo);
}
private int findByRecursion(int n, int[] memo) {
//递归出口
if(n == 0 || n == 1){
return 1;
}
//判断之前是否已被计算过
if(memo[n] != -1){
return memo[n];
}
//执行记忆化
memo[n] = findByRecursion(n - 1,memo) + findByRecursion(n - 2,memo);
return memo[n];
}
3.动态规划
public int climbStairs2(int n) {
/*动态规划
时间复杂度O(n),空间复杂度O(n)
* */
int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
4.状态压缩
public int climbStairs3(int n) {
/*动态规划,状态压缩
时间复杂度O(n),空间复杂度O(1)
* */
int pre = 1;
int cur = 1;
int temp;
for (int i = 2; i <= n; i++) {
temp = cur;
cur = cur + pre;
pre = temp;
}
return cur;
}
看到一篇写的比较好的文章: https://leetcode-cn.com/problems/climbing-stairs/solution/cong-zhi-jue-si-wei-fen-xi-dong-tai-gui-hua-si-lu-/
|