随想录训练营Day45 | DP - - 70. 爬楼梯, 322. 零钱兑换, 279.完全平方数

57 阅读2分钟

随想录训练营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. 零钱兑换

思路img_45_1.png

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];
    }
}

两个注意点

  1. 对于数组 dp 的初始化有误 在 Java 中,for (int i : dp) 这种循环语法叫做 foreach 循环,它用于遍历数组或集合中的元素。在 foreach 循环中,变量 i 被赋值为数组 dp 中的每个元素,但是这种方式并不会修改数组中的元素。 因此,在上述代码中使用 foreach 循环初始化数组 dp 时,实际上只是将局部变量 i 赋值为数组 dp 中的每个元素,而数组 dp 中的元素并没有被正确地初始化为 Integer.MAX_VALUE。最终导致程序输出错误结果。 foreach 循环主要用于遍历集合类或数组等数据结构,而不是对它们进行修改。因此,在需要遍历集合中的元素并执行某些操作时,可以使用 foreach 循环
  2. 只有dp[j-coins[i]]不是初始最大值时,该位才有选择的必要 eg:img_45_2.png

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];
    }
}