509. 斐波那契数
很简单的动规入门题,但简单题使用来掌握方法论的,还是要有动规五部曲来分析
- 原始的dp
class Solution {
public int fib(int n) {
if(n <= 1) return n;
int[] dp = new int[n + 1];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++){
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
- 当然可以发现,我们只需要维护两个数值就可以了,不需要记录整个序列。
class Solution {
public int fib(int n) {
if(n <= 1) return n;
int[] dp = new int[2];
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; i++){
int sum = dp[0] + dp[1];
dp[0] = dp[1];
dp[1] = sum;
}
return dp[1];
}
}
70. 爬楼梯
把上面这个递推公式弄明白这道题就明白了
1阶 1步 1种方法
2阶 1 1步;一步两个楼梯;2种方法
明白了3阶就全懂了
3阶 :就是在2阶的基础上在迈1步就到了相当于有两种,也可以在1阶的基础上连续1步,总共3种(1阶 + 2阶)
4阶:就是在2阶或3阶的基础上迈,2阶情况就是只能再迈两步,3阶情况是只能迈1步,最后就是总情况是5种(2阶 + 3阶)
当时自己思考有这情况,就是开始2阶,之后的二阶不也有两种情况,相当于光二阶就有4种情况吗,不是的,因为这样看会多出一种情况就是记录3阶时1111会出现两次;
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
if(n <= 2) return n;
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; i++){
dp[i] = dp[i - 1] + dp[i - 2];
}
return dp[n];
}
}
这道题开始写的时候当n=1时出现了问题,因为没有写if判断,5到10行都是针对n=3这种情况
746. 使用最小花费爬楼梯
首先需要明确的是站在0位置也就是10楼梯,不消耗体力值,只有向上爬才需要,楼顶是下标为3的位置(看示例1能看出来)
dp[i] 表示到达第i台阶所花费的最少体力为dp[i]
class Solution {
public int minCostClimbingStairs(int[] cost) {
int[] dp = new int[cost.length + 1];
dp[0] = 0;
dp[1] = 0;
for(int i = 2; i <= dp.length - 1; i++){
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[dp.length - 1];
}
}
- 官方
// 方式一:第一步不支付费用
class Solution {
public int minCostClimbingStairs(int[] cost) {
int len = cost.length;
int[] dp = new int[len + 1];
// 从下标为 0 或下标为 1 的台阶开始,因此支付费用为0
dp[0] = 0;
dp[1] = 0;
// 计算到达每一层台阶的最小费用
for (int i = 2; i <= len; i++) {
dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
}
return dp[len];
}
}