学习目标:
动态规划五部曲:
① 确定dp[i]的含义
② 求递推公式
③ dp数组如何初始化
④ 确定遍历顺序
⑤ 打印递归数组 ---- 调试
引用自代码随想录!
60天训练营打卡计划!
学习内容:
509.斐波那契数
- 动态规划五步曲:
① 确定dp[i]的含义 : 第i个斐波那契数的值
② 求递推公式 : dp[i] = dp[i-1] +dp[i-2]
③ dp数组如何初始化 : dp[0] = 1 dp[1] = 1
④ 确定遍历顺序 : 从前向后
// 动态规划
class Solution {
public int fib(int n) {
int[] dp = new int[n + 1];
dp[0] = 0;
if(n == 0) return dp[0];
dp[1] = 1;
if(n == 1) return dp[1];
for(int i = 2; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
// 递归实现
class Solution {
// 该递归的传入参数应该是 F(n - 1) 和 F(n - 2) 和循环次数,返回值应该是 F(n)
private int traversal(int pre, int cur, int num){
// 递归结束条件
if(num == 0) return pre + cur;
// 最小递归的逻辑
int sum = traversal(cur, pre+cur, num-1);
// 这里的return是为了在最深的递归结束之后,其他较浅的递归逐层向上返回结果。
return sum;
}
public int fib(int n) {
int pre = 0;
if(n == 0) return pre;
int cur = 1;
if(n == 1) return cur;
return traversal(pre, cur, n-2);
}
}
70.爬楼梯
- 动态规划五步曲:
① 确定dp[i]的含义 : 到第i级台阶有dp[i]种方法
② 求递推公式 : dp[i] = dp[i-1] +dp[i-2]
③ dp数组如何初始化 : dp[1] = 1 dp[2] = 2
④ 确定遍历顺序 : 从前向后 - 这个规律只是恰好可以和递推关系对应起来,但是很难说明真实的数量间的关系。
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[1] = 1;
if(n == 1) return dp[1];
dp[2] = 2;
if(n == 2) return dp[2];
for(int i = 3; i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
class Solution {
private int traversal(int pre, int cur, int num){
int next = pre + cur;
if(num == 0) return next;
return traversal(cur, next, num - 1);
}
public int climbStairs(int n) {
int pre = 1;
if(n == 1) return pre;
int cur = 2;
if(n == 2) return cur;
return traversal(pre, cur, n - 3);
}
}
746. 使用最小花费爬楼梯
-
动态规划五步曲:
① 确定dp[i]的含义 : 到第i级台阶的最小体力消耗
② 求递推公式 : dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]) ,其中cost[i-1]是在第i-1阶台阶时的体力消耗。
③ dp数组如何初始化 : dp[0] = 0 dp[1] = 0 cost[0] = 10 cost[1] = 15
④ 确定遍历顺序 : 从前向后 -
在实现的过程中还有一些其他的细节,比如说最大阶要比cost的长度大1.
class Solution {
public int minCostClimbingStairs(int[] cost) {
int size = cost.length;
// 台阶的最大高度一定比开销大1
int[] dp = new int[size+1];
dp[0] = 0;
dp[1] = 0;
if(size == 0 || size == 1) return 0;
for(int i = 1; i < size; i++){
// 因为递推公式是卡着目标线写出来的,故一定可以达到最高的台阶
dp[i+1] = Math.min(dp[i-1] + cost[i-1], dp[i] + cost[i]);
}
// 这里返回的是最高级的台阶
return dp[size];
}
}
学习时间:
- 上午两个半小时,整理文档半小时。