算法学习day38-动态规划

零钱兑换

核心思路

  • 就是完全背包的写法, 只是这个题是求最小值, 所以初始化的时候不能初始化0, 而是Integer.max_value

  • 以及赋值的时候, 如果dp[j - coin] = max, 就跳过, 说明这个硬币无法兑换=j

    java 复制代码
    public static int coinChange(int[] coins, int amount) {
        //dp[i] = 下标为i的时候 能填满的最少硬币数
        //推导
        //如果不放coins[i], dp[j]不变
        //如果放了coins[i], dp[j] = dp[j - coins[i]] + 1
        //初始化
        int[] dp = new int[amount + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for (int coin : coins) {
            for (int j = coin; j <= amount; j++) {
                if(dp[j - coin] == Integer.MAX_VALUE){
                    continue;
                }
                dp[j] = Math.min(dp[j], dp[j - coin] + 1);
            }
        }
        return dp[amount] == Integer.MAX_VALUE ? 0 : dp[amount];
    }

完全平方数

核心思路

  • 和零钱兑换思路几乎一致

  • dp定义: dp[j]代表的是 和为j的完全平方数的最小数量

  • 只是n即是物品, 也是背包容量

    java 复制代码
    public static int numSquares(int n) {
        int[] dp = new int[n + 1];
        Arrays.fill(dp, Integer.MAX_VALUE);
        dp[0] = 0;
        for (int i = 1; i <= n; i++) {
            long sqrt = (long) Math.sqrt(i);
            //不是完全平方数就跳过
            if (sqrt * sqrt != (long) i) continue;
            for (int j = i; j <= n; j++) {
                if (dp[j - i] == Integer.MAX_VALUE) continue;
                dp[j] = Math.min(dp[j], dp[j - i] + 1);
            }
        }
        return dp[n];
    }
  • 算法优化后

    • 外层i直接平方, 这样就不用判断i是否是完全平方数, i * i 一定是从小到大的完全平方数, 1、4、9等
    java 复制代码
    int[] dp = new int[n + 1];
    Arrays.fill(dp, Integer.MAX_VALUE);
    dp[0] = 0;
    for (int i = 1; i * i <= n; i++) {
        for (int j = i * i; j <= n; j++) {
            if (dp[j - i * i] == Integer.MAX_VALUE) continue;
            dp[j] = Math.min(dp[j], dp[j - i * i] + 1);
        }
    }
    return dp[n];

单词拆分

核心思路

  • 还是完全背包问题
  • 但是该题 不是求组合,而是排列
    • 因为单词是要求有序的,比如 leetcode,[code,leet], 就要先leet, 再code
例如
  • 输入: s = "catsanddog", wordDict = ["cat", "cats", "and", "sand", "dog"]

  • i = 3: j=0 匹配 "cat",dp[3] = T。

  • i = 4: j=0 匹配 "cats",dp[4] = T。

  • i = 7 ("catsand"):

  • 尝试 j = 3: dp[3] 是 T (cat),剩下 s[3:7] 是 "sand"。字典有 "sand",所以 dp[7] = T。

  • 尝试 j = 4: dp[4] 是 T (cats),剩下 s[4:7] 是 "and"。字典也有 "and",所以 dp[7] 再次被确认是 T。
    (只要有一个 j 能通,dp[7] 就是 true)

  • i = 10: j=7 匹配 "dog",且 dp[7] 是 T,所以 dp[10] = T。

  • 结果: 成功。

    java 复制代码
    public static boolean wordBreak(String s, List<String> wordDict) {
      boolean[] dp = new boolean[s.length() + 1];
      //dp的定义: 下标为i, 代表的是 从 0...i-1的单词能够被wordDict拼接而来
      dp[0] = true;
      for (int i = 1; i <= s.length(); i++) {
        for (int j = 0; j < i; j++) {
          dp[i] = dp[j] && wordDict.contains(s.substring(j, i));
          if (dp[i]) break;
        }
      }
      return dp[s.length()];
    }
相关推荐
多恩Stone3 小时前
【3D AICG 系列-6】OmniPart 训练流程梳理
人工智能·pytorch·算法·3d·aigc
Aliex_git3 小时前
跨域请求笔记
前端·网络·笔记·学习
tritone3 小时前
使用阿贝云免费云服务器学习Vagrant,是一次非常顺畅的体验。作为一名开发者
服务器·学习·vagrant
历程里程碑3 小时前
普通数组----轮转数组
java·数据结构·c++·算法·spring·leetcode·eclipse
pp起床3 小时前
贪心算法 | part02
算法·leetcode·贪心算法
sin_hielo3 小时前
leetcode 1653
数据结构·算法·leetcode
2501_901147833 小时前
面试必看:优势洗牌
笔记·学习·算法·面试·职场和发展
YuTaoShao3 小时前
【LeetCode 每日一题】3634. 使数组平衡的最少移除数目——(解法二)排序 + 二分查找
数据结构·算法·leetcode
wangluoqi3 小时前
26.2.6练习总结
数据结构·算法