随想录训练营Day45 | DP - - 70. 爬楼梯, 322. 零钱兑换, 279.完全平方数
标签: LeetCode闯关记
70. 爬楼梯
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n + 1];
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= 2; j++) {
if (i >= j) {
dp[i] += dp[i - j];
}
}
}
return dp[n];
}
}
322. 零钱兑换
思路
class Solution {
public int coinChange(int[] coins, int amount) {
int max = Integer.MAX_VALUE;
int[] dp = new int[amount+1];
// 犯错误1:对于数组 dp 的初始化有误。在循环初始化时,应该使用索引进行赋值,而不是使用 foreach 循环。
// for (int n : dp) {
// n = Integer.MAX_VALUE;
// }
for (int i = 0; i < amount+1; i++) {
dp[i] = max;
}
dp[0] = 0;
for (int i = 0; i < coins.length; i++) {
for (int j = coins[i]; j <= amount; j++) {
if(dp[j- coins[i]] != max){//(犯错误2: 这里的判断很重要,否则会发生溢出,下面会举例子)
// System.out.println("dp[j- coins[i]] + 1=" + (dp[j- coins[i]] + 1));
dp[j] = Math.min(dp[j], dp[j- coins[i]] + 1);
// System.out.println("i=" + i + " j=" + j + " dp[j]=" + dp[j]);
}
}
}
return dp[amount] == max? -1: dp[amount];
}
}
两个注意点
- 对于数组 dp 的初始化有误 在 Java 中,
for (int i : dp)这种循环语法叫做foreach循环,它用于遍历数组或集合中的元素。在foreach循环中,变量i被赋值为数组 dp 中的每个元素,但是这种方式并不会修改数组中的元素。 因此,在上述代码中使用 foreach 循环初始化数组 dp 时,实际上只是将局部变量 i 赋值为数组 dp 中的每个元素,而数组 dp 中的元素并没有被正确地初始化为 Integer.MAX_VALUE。最终导致程序输出错误结果。foreach循环主要用于遍历集合类或数组等数据结构,而不是对它们进行修改。因此,在需要遍历集合中的元素并执行某些操作时,可以使用 foreach 循环只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要eg:
279.完全平方数
class Solution {
public int numSquares(int n) {
int[] dp = new int[n+1];
int max = Integer.MAX_VALUE;
for (int i = 0; i <= n ; i++) {
dp[i] = max;
}
dp[0] = 0;
for (int i = 1; i*i <= n ; i++) {
for (int j = i*i; j <= n ; j++) {
if(dp[j - i*i] != max){
dp[j] = Math.min(dp[j], dp[j- i*i] + 1);
}
}
}
return dp[n];
}
}

