算法学习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()];
    }
相关推荐
IronMurphy6 小时前
【算法四十三】279. 完全平方数
算法
墨染天姬6 小时前
【AI】Hermes的GEPA算法
人工智能·算法
papership7 小时前
【入门级-数据结构-3、特殊树:完全二叉树的数组表示法】
数据结构·算法·链表
smj2302_796826527 小时前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
酿情师7 小时前
yihan:一款面向连续网页学习的智能侧边栏插件
学习·学习方法·工具·学习工具
Beginner x_u7 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
瞎某某Blinder8 小时前
DFT学习记录[6]基于 HES06的能带计算+有效质量计算
python·学习·程序人生·数据挖掘·云计算·学习方法
love在水一方9 小时前
VLN 入门学习计划 —— 基于 InternNav
学习
_深海凉_10 小时前
LeetCode热题100-寻找两个正序数组的中位数
算法·leetcode·职场和发展
旖-旎11 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历