大家好,我是晴天学长,第二个记忆化搜索练习,需要的小伙伴可以关注支持一下哦!后续会继续更新的。
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶
示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶
提示:
1 <= n <= 45
1.定义一个整型数组 memo,用于存储记忆化搜索的结果。
2.创建 climbStairs 方法来启动算法。在该方法中,初始化 memo 数组,并将其所有元素初始化为 -1。
3.调用 dfs 方法,将目标阶数 n 作为参数,并返回结果。
4.在 dfs 方法中,首先检查是否已经搜索过当前阶数 n 的结果。如果在 memo 数组中存在已计算的值,则直接返回该值作为结果,避免重复计算。
1)如果当前阶数 n 小于 0,表示没有可行的爬楼梯方式,返回 0。
2)如果当前阶数 n 等于 1,表示只有一种方式到达,返回 1。
3)如果当前阶数 n 等于 2,表示有两种方式到达,返回 2。
4)否则,根据动态规划的思想,当前阶数 n 的结果等于爬到 n-1 阶和 n-2 阶的方法数之和。使用递归调用 dfs 方法,分别计算到达 n-1 阶和 n-2 阶的方法数,并将它们相加。
5)将计算得到的结果存储在 memo 数组中,以备后续使用。
6)返回当前阶数 n 的结果作为最终答案。
//方法1
class Solution {
int[] memo;
public int climbStairs(int n) {
memo = new int[n+1];
Arrays.fill(memo, -1);
return dfs(n);
}
private int dfs(int n) {
if (n < 0) {
return 0;
}
if (n == 2) {
return 2;
} else if (n == 1) {
return 1;
}
if (memo[n] != -1) {
return memo[n];
}
int result = dfs(n - 1) + dfs(n - 2);
memo[n] = result;
return result;
}
}
//放法2 dp动态规划
class Solution {
int[] dp;
public int climbStairs(int n) {
dp = new int[46];
dp[1] = 1;
dp[2] = 2;
if (n<=2){
return dp[n];
}
for (int i = 3; i <= n; i++) {
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
试题链接: