【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分

本文主要是介绍【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一、做题心得

二、题目与题解

题目一:322. 零钱兑换

题目链接

题解:动态规划--完全背包 

题目二: 279.完全平方数

题目链接

题解:动态规划--完全背包

题目三:139.单词拆分

题目链接

题解:动态规划--完全背包

三、小结


一、做题心得

今天来到了代码随想录动态规划章节的Part6,依旧是完全背包问题的应用。相对于前边直接套用模板,今天的题目难度相对较大一点,尤其是单词拆分这道题,bool型dp数组的使用,和之前做的题就有很大的不同。

话不多说,直接开始今天的内容。

二、题目与题解

题目一:322. 零钱兑换

题目链接

322. 零钱兑换 - 力扣(LeetCode)

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11输出:3解释:11 = 5 + 5 + 1

示例 2:

输入:coins = [2], amount = 3输出:-1

示例 3:

输入:coins = [1], amount = 0
输出:0

提示:

  • 1 <= coins.length <= 12
  • 1 <= coins[i] <= 231 - 1
  • 0 <= amount <= 104
题解:动态规划--完全背包 

这道题属于是完全背包求最值问题--求得凑成总金额所需的最少得硬币数量,当然,本质上讲,也是组合数问题。

首先就是dp数组的定义与初始化:dp[j]表示凑成金额 j 所需的最少硬币数量--注意:dp[j]必须初始化为一个较大的数,以防在后续min()函数处直接被初始值覆盖,还有就是初始化 dp[0] = 0

然后就是这道题的关键部分:如果存在一种或多种方式可以组成金额 j - coins[i],那么加上一个coins[i]之后就可以凑成金额 j。

这里直接看代码(含注释):

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount + 1, INT_MAX);        //dp[j]表示凑成金额 j 所需的最少硬币数量--注意:dp[j]必须初始化为一个最大的数,以防在后续min()函数处直接被初始值覆盖dp[0] = 0;          //初始化dp[0]为0,表示组成金额0不需要任何硬币for (int i = 0; i < coins.size(); i++) {            //先遍历物品再遍历背包(先遍历背包也可以)for (int j = coins[i]; j <= amount; j++) {              //正序遍历背包(金额)-- 表示可重复使用硬币:注意,这里从coins[i]开始遍历,因为如果金额小于当前硬币的面值,那么当前硬币无法使用(保证j - coins[i]大于0)if (dp[j - coins[i]] != INT_MAX) {      //说明存在一种或多种方式可以组成金额 j - coins[i] ,这时再加上一个当前硬币 coins[i],就可以组成金额 j -- 间接性说明此时可以凑成总金额dp[j] = min(dp[j - coins[i]] + 1, dp[j]);       //不断更新凑成金额 j 所需的最少的硬币个数}}}if (dp[amount] == INT_MAX) {      //没有任何一种硬币组合能组成总金额amountreturn -1;}else    return dp[amount];}
};

题目二: 279.完全平方数

题目链接

279. 完全平方数 - 力扣(LeetCode)

给你一个整数 n ,返回 和为 n 的完全平方数的最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,149 和 16 都是完全平方数,而 3 和 11 不是。

示例 1:

输入:n = 12输出:3 解释:12 = 4 + 4 + 4

示例 2:

输入:n = 13输出:2解释:13 = 4 + 9
 

提示:

  • 1 <= n <= 104
题解:动态规划--完全背包

这道题和上一道零钱兑换思路上基本一致,需要注意的就是如何实现完全平方数的列举。

这里先看看我的代码:

 直接新建一个数组,存放每个数字的平方即可。-- 显然,这样时间复杂度和空间复杂度都加大了。

我们可以直接在遍历物品与背包的过程中实现对完全平方数的操作。

如下是修改后的代码:

class Solution {
public:int numSquares(int n) {/* 完全背包问题--一维dp */vector<int> dp(n + 1, INT_MAX);dp[0] = 0;for (int i = 1; i * i <= n; i++) {             //先遍历物品再遍历背包for (int j = i * i; j <= n; j++) {      //正序遍历背包--这里的for循环直接实现了j为完全平方数dp[j] = min(dp[j - i * i] + 1, dp[j]);}}return dp[n];}
};

题目三:139.单词拆分

题目链接

139. 单词拆分 - 力扣(LeetCode)

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true

注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。

示例 1:

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。

示例 2:

输入: s = "applepenapple", wordDict = ["apple", "pen"]
输出: true
解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。注意,你可以重复使用字典中的单词。

示例 3:

输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"]
输出: false

提示:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s 和 wordDict[i] 仅由小写英文字母组成
  • wordDict 中的所有字符串 互不相同
题解:动态规划--完全背包

这道题实际上的意思就是判断是否能从字典中选择单词构成字符串s -- 需要注意的就是每个单词可以重复使用,而为了构成字符串,一定是讲求顺序的 -- 这就容易联想到完全背包的排列数问题

在这里,就应该定义bool类型的dp数组,dp[i]表示字符串s的前i个字符是否可以被拆分成若干个字典(wordDict)中出现的单词。

初始化整个 dp 数组为 false,而 dp[0] = true。

排列数问题--先背包再物品,这里用到了str()函数,用于截取字符串的子串部分(这里需要注意子串部分的长度),判断是否有某个单词与之匹配。

代码如下:

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {vector<bool> dp(s.size() + 1, false);          //定义bool类型的dp数组,dp[i]表示字符串s的前i个字符是否可以被拆分成若干个字典(wordDict)中出现的单词dp[0] = true;       //初始化dp[0] = 0/*  排列数问题--先背包再物品  */for(int i = 1; i <= s.size(); i++) {            //正序遍历字符串s(背包)    for(auto word: wordDict) {          //遍历单词(物品):这样写更直观int size = word.size();    //记录当前单词长度(背包问题中的物品体积)   if ((i - size) >= 0 && s.substr(i - size, size) == word) {        //从s中提取的子字符串s.str(i - size, size)和字典中当前单词 word 匹配时--注意这里需要保证(i - size) >= 0即str(start, len)提取子串的初始位置start不能为负dp[i] = dp[i] || dp[i - size];       //表示如果 dp[i - size] 为真,则 dp[i] 也应为真 }}       }return dp[s.size()];        //整个字符串进行判断}   
};

三、小结

今天的打卡到此也就结束了,完全背包问题暂时也就告一段落,后边会继续加油!

这篇关于【代码随想录训练营第42期 Day38打卡 - 动态规划Part6 - LeetCode 322. 零钱兑换 279.完全平方数 139.单词拆分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1101395

相关文章

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

MySQL数据库函数之JSON_EXTRACT示例代码

《MySQL数据库函数之JSON_EXTRACT示例代码》:本文主要介绍MySQL数据库函数之JSON_EXTRACT的相关资料,JSON_EXTRACT()函数用于从JSON文档中提取值,支持对... 目录前言基本语法路径表达式示例示例 1: 提取简单值示例 2: 提取嵌套值示例 3: 提取数组中的值注意

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

JAVA调用Deepseek的api完成基本对话简单代码示例

《JAVA调用Deepseek的api完成基本对话简单代码示例》:本文主要介绍JAVA调用Deepseek的api完成基本对话的相关资料,文中详细讲解了如何获取DeepSeekAPI密钥、添加H... 获取API密钥首先,从DeepSeek平台获取API密钥,用于身份验证。添加HTTP客户端依赖使用Jav

Java实现状态模式的示例代码

《Java实现状态模式的示例代码》状态模式是一种行为型设计模式,允许对象根据其内部状态改变行为,本文主要介绍了Java实现状态模式的示例代码,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来... 目录一、简介1、定义2、状态模式的结构二、Java实现案例1、电灯开关状态案例2、番茄工作法状态案例

Java使用POI-TL和JFreeChart动态生成Word报告

《Java使用POI-TL和JFreeChart动态生成Word报告》本文介绍了使用POI-TL和JFreeChart生成包含动态数据和图表的Word报告的方法,并分享了实际开发中的踩坑经验,通过代码... 目录前言一、需求背景二、方案分析三、 POI-TL + JFreeChart 实现3.1 Maven

nginx-rtmp-module模块实现视频点播的示例代码

《nginx-rtmp-module模块实现视频点播的示例代码》本文主要介绍了nginx-rtmp-module模块实现视频点播,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录预置条件Nginx点播基本配置点播远程文件指定多个播放位置参考预置条件配置点播服务器 192.

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

Java导出Excel动态表头的示例详解

《Java导出Excel动态表头的示例详解》这篇文章主要为大家详细介绍了Java导出Excel动态表头的相关知识,文中的示例代码简洁易懂,具有一定的借鉴价值,有需要的小伙伴可以了解下... 目录前言一、效果展示二、代码实现1.固定头实体类2.动态头实现3.导出动态头前言本文只记录大致思路以及做法,代码不进