当前位置: 首页 > article >正文

代码随想录|动态规划 322. 零钱兑换 279.完全平方数 139.单词拆分

322. 零钱兑换

题目

参考文章

思路:本题其实也是完全背包问题

dp[j]:凑足总额为j所需钱币的最少个数为dp[j]

但是在初始化dp数组时,要初始化为最大的值,因为从题目知道,要得到的是最少的硬币个数,所以在取min时,为了防止会被初始值覆盖的风险,得把初始值设置为最大值

递推公式:dp[j]=min(dp[j-conis[i]]+1,dp[j]);

这里为什么是 +1 呢?因为题目是求硬币个数,所以要把当前的硬币加上,就直接加1即可。

如果求组合数就是外层for循环遍历物品,内层for遍历背包

如果求排列数就是外层for遍历背包,内层for循环遍历物品

本题不强调排列或组合

代码:

class Solution {
    public int coinChange(int[] coins, int amount) {
        int max=Integer.MAX_VALUE;
        int[] dp=new int[amount+1];
        
        for(int i=0;i<=amount;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){//只有当要取的数组值不是最大值,最后得到的最小值才有意义
                    dp[j]=Math.min(dp[j-coins[i]]+1,dp[j]);
                }
            }
        }

        return dp[amount]==max?-1:dp[amount];
    }
}

279.完全平方数

题目

参考文章

思路:本题思路和 322零钱兑换相似。也是求最少数量,仍初始化dp数组为最大值。然后一次次的最最小值。

同时有因为完全平方数中有 1 所以无论什么数,都可以由1拼凑出来

代码:

class Solution {
    public int numSquares(int n) {
        int max=Integer.MAX_VALUE;
        int[] dp=new int[n+1];

        for(int i=0;i<=n;i++){
            dp[i]=max;
        }

        dp[0]=0;

        for(int i=1;i*i<=n;i++){//因为由题目知道,其要的是完全平方数,所以直接把 i*i作为当前的物品,n为背包容量
            for(int j=i*i;j<=n;j++){
                dp[j]=Math.min(dp[j-i*i]+1,dp[j]);
            }
        }


        return dp[n];
    }
}

139.单词拆分

题目

参考文章

思路:单词就是物品,字符串s就是背包

dp数组含义 :dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词

 if([j, i] 这个区间的子串出现在字典里 && dp[j]是true) 那么 dp[i] = true  (j<i)

dp[0]表示如果字符串为空的话,说明出现在字典里

dp[0]=true,其他的为false

本题要求的是排列数,为什么呢?因为在字典集中,同样的单词组,如果顺序变了,它最后得到的字符都是不一样的,所以强调排列数。

排列数(即使是相同元素,但是顺序不同,也作为一个分组)

组合数(把相同元素的都认为只有一个组)

这里j<i,是因为我们后面要取s中从j到i位置的字符是否在set集合中,如果在就表示可以组成,把当前的点改为true

这里的dp[j]其实就是说,前一个单词比较的时候,是确定可以组成一个s的一部分的,才可以设置下一个也可以组成s的一部分,如果dp[j]的时候都不能组成s的一部分,这里即使单词配对正确,也是不能得到s字符串

代码:

class Solution {
    public boolean wordBreak(String s, List<String> wordDict) {
        HashSet<String> set=new HashSet<>(wordDict);
        boolean[] dp=new boolean[s.length()+1];
        dp[0]=true;

        for(int i=1;i<=s.length();i++){//先遍历背包
            for(int j=0;j<i&&!dp[i];j++){//再遍历物品,这里j<i,是因为我们后面要取s中从j到i位置的字符是否在set集合中,如果在就表示可以组成,把当前的点改为true
                if(set.contains(s.substring(j,i))&&dp[j]){//这里的dp[j]其实就是说,前一个单词比较的时候,是确定可以组成一个s的一部分的,才可以设置下一个也可以组成s的一部分,如果dp[j]的时候都不能组成s的一部分,这里即使单词配对正确,也是不能得到s字符串
                    dp[i]=true;
                }
            }
        }

        return dp[s.length()];
    }
}


http://www.kler.cn/a/525571.html

相关文章:

  • (Java版本)基于JAVA的网络通讯系统设计与实现-毕业设计
  • 使用Python爬虫获取1688商品拍立淘API接口(item_search_img)的实战指南
  • 【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(一)
  • MySQL通过binlog恢复数据
  • 51单片机开发:定时器中断
  • Ollama 运行从 ModelScope 下载的 GGUF 格式的模型
  • Java实现LFU缓存策略实战
  • 31. C语言 命令行参数
  • 剑指 Offer II 011. 0 和 1 个数相同的子数组
  • 【开源免费】基于SpringBoot+Vue.JS公交线路查询系统(JAVA毕业设计)
  • unity使用AVpro插件播放视频,打包安卓系统总是失败
  • R语言统计分析——ggplot2绘图4——刻面
  • 21.2-工程中添加FreeRTOS(掌握) 用STM32CubeMX添加FreeRTOS
  • H3CNE-31-BFD
  • WEB集群6-10天
  • 深入解析 C++17 中的 std::not_fn
  • 数据结构--差分数组(含题目)<基础入门>
  • 2025创业思路和方向有哪些?
  • 最新版仿天涯论坛系统源码带后台
  • 30组成字符串ku的最大次数-青训营刷题
  • 将点云转换为 3D 网格:Python 指南
  • 分享几个好用的Edge扩展插件
  • 自制一个入门STM32 四足机器人具体开发顺序
  • Pwn 入门核心工具和命令大全
  • 简要介绍C语言与c++共有的数学函数
  • Versal - 基础3(AXI NoC 专题+仿真+QoS)