代码随想录Day49

news2025/6/21 16:31:41

今天继续学习动规解决完全背包问题。

322.零钱兑换

给你一个整数数组 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.本题因为每种硬币数量无线,可以看出是一道完全背包问题,总金额即为背包重量,每一种硬币即为物品。

2.首先想dp数组含义,dp[j]代表装满容量为j的背包所需要的最少物品个数

3.然后想递推公式,对于当前物品有两种选择,放或者不放,放入背包的话即为dp[j - coins[i]] + 1(因为要求的是最少物品个数,因此是加1!),不放入背包即为dp[j],对这两者取最小值即为递推公式

4.然后想初始化,题目示例已经告诉我们dp[0] = 0,而递推公式中涉及取最小值,因此其他我们初始化为INT_MAX

5.最后想遍历顺序,因为本题要求的是最少数量,而元素的顺序并不会影响装满背包的最少物品数量,因此无论先物品还是先背包都可以。

class Solution {
public:
    int coinChange(vector<int>& coins, int amount) {
        vector<int> dp(amount + 1, INT_MAX);
        dp[0] = 0;

        for(int i = 0; i < coins.size(); i++){
            for(int j = coins[i]; j <= amount; j++){
                if(dp[j - coins[i]] != INT_MAX){
                    dp[j] = min(dp[j], dp[j - coins[i]] + 1);
                }
            }
        }
        if(dp[amount] == INT_MAX) return -1;
        return dp[amount];
    }
};

启发:

1.本题尽管基本思路和代码都相对好想,但还是会有细节的问题。在第一次提交后报了如下错误:

 将报错示例代入后就会发现问题:如果在遍历过程中dp[j - coins[i]]依旧等于INT_MAX,说明对于当前物品,当前背包没办法装满,对于这种情况我们应当跳过,因此在for循环取值时仍然需要一个条件判断语句来判断dp[j - coins[i]]是否等于INT_MAX。

279.完全平方数

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

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

示例 1:

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

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

思路:

1.本题实质上和上一道题一模一样,背包容量即为给出的n,物品是各个完全平方数。因此详细思路就不再一一列出。

class Solution {
public:
    int numSquares(int n) {
        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++){
                if(dp[j - i * i] != INT_MAX){
                    dp[j] = min(dp[j], dp[j - i * i] + 1);
                }
            }
        }

        return dp[n];
    }
};

启发:

1.本题仍然有那么一些上一题没有的细节上的东西。如for循环时,i,j各自的循环条件是什么?j代表背包容量因此很容易就能想到j <= n,而对于i,一开始想的是不设限制,直到某个具体条件时直接让循环break,但这样就有一个问题:这个具体条件是什么?我们要求最少数量,但除非遍历结束不然也不能保证你当前已经取到的值就是最小数量。但有一点是肯定的,因为要用完全平方数来组成我们的n,因此该完全平方数显然不能大于n,因此i的循环条件为i * i <= n。

139.单词拆分

给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s 。

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

示例 1:

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

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

思路:

1.本题乍一看会先想到KMP算法,不过KMP算法的应用场景与本题相似但不完全相同,毕竟本题要看字典中的单词能否拼接成字符串。由于单词可以重复使用,我们可以将其抽象为一个完全背包问题,原字符串长度即为背包容量,字典中的每一个单词即为物品。

2.首先想dp数组含义。本题dp数组不同于之前所有的dp数组,因为本题要求的是是否能组成,并不单纯是求一个数值了,因此dp数组得设置为布尔类型,dp[i] = true 表示长度为i的字符串能够被字典中的单词构成。

3.然后想递推公式,本题递推公式也相对没那么好像,因为没有一个确切的公式。对于dp[i]能否被字典中的单词构成,我们得看前面的部分。此时假设前面一个位置为j,那么dp[i] = true的条件是dp[j] = true(即位置j及之前的元素能够被字典中的单词组成),且区间为 [j , i] 部分的字符串也能被字典中的单词组成

4.然后想初始化,dp[0]一定得是true,因为后续都是由dp[0]推导出来的,其他的为false即可

5.然后想遍历顺序,本题对于元素的顺序实际上是有要求的,拿题目中的示例2举例子,只要有两个apple和一个pen就可以组成字符串,但是这三个字符串的组合不一定是我们要的字符串。因此本题实际上求的是排列数,我们必须要元素顺序也对应上我们的原字符串,所以要先遍历背包后遍历物品

class Solution {
public:
    bool wordBreak(string s, vector<string>& wordDict) {
        unordered_set<string> set(wordDict.begin(), wordDict.end());//用于查询字典

        vector<bool> dp(s.size() + 1, false);
        dp[0] = true;

        for(int i = 1; i <= s.size(); i++){
            for(int j = 0; j < i; j++){
                string tmp = s.substr(j, i - j);
                if(dp[j] == true && set.find(tmp) != set.end()){
                    dp[i] = true;
                }
            }
        }

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

启发:

1.个人觉得似乎一旦涉及上字符串题目就会难很多(思路可能相对于代码都会稍微好一点),本题首次将dp数组设置为布尔变量容器,且用到了哈希表来作为字典辅助查询,递推公式的思想也十分巧妙,需要更进一步的理解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/411361.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虹科分享 | 使用IOTA检查受3CX DLL旁加载攻击影响的客户端 | 网络性能监控

2023年3月底&#xff0c;VoIP制造商3CX&#xff08;流行的互联网语音协议&#xff08;VoIP&#xff09;专用交换机&#xff08;PBX&#xff09;电话系统的开发商&#xff09;遭到DLL旁加载攻击。他们的软件被大约60万家公司和1200万用户使用&#xff0c;其中包括梅赛德斯-奔驰、…

人工智能中的监督学习到底是啥?其应用方向有哪些?

人工智能&#xff08;Artificial Intelligence, AI&#xff09;是一门致力于使机器能够像人类一样进行智能决策和行为的学科。监督学习&#xff08;Supervised Learning&#xff09;是人工智能领域中的一种重要学习方式&#xff0c;通过使用标注好的样本数据来训练模型&#xf…

零基础如何入门网络安全?【2023最新】

前言 最近收到不少关注朋友的私信和留言&#xff0c;大多数都是零基础小友入门网络安全&#xff0c;需要相关资源学习。其实看过的铁粉都知道&#xff0c;之前的文里是有过推荐过的。新来的小友可能不太清楚&#xff0c;这里就系统地叙述一遍。 01.简单了解一下网络安全 说白…

Linux 操作系统原理 — 内核协议栈收包/发包流程

目录 文章目录目录关键技术NIC DMAKernel 中的 sk_buff 与 sk_bufferKernel 中的 Rx/Tx RingBuffer Descriptor Table中断收包机制NAPI 收包机制多队列网卡内核协议栈收包/发包流程概览内核协议栈收包流程详解驱动程序层&#xff08;数据链路层&#xff09;VLAN 协议族Linux Br…

基于MATLAB的语音识别仿真系统

本文实现的语音识别系统&#xff0c;主要是对语音识别的特征参数的提取和识别模型的匹配&#xff0c;进行深入的研究。首先,对语音识别进行了概述&#xff0c;给出了语音识别的系统框架。然后就是如何实现语音识别的问题&#xff0c;这个过程可分为两个部分:第一个是语音特征参…

【Ruby 2D】【unity learn】控制敌人随机运动以及动画控制

前两天考完蓝桥杯稍微休息了一下&#xff0c;昨天做了一个动画控制&#xff0c;但是想到写出来可能会字很多&#xff0c;我就搁置到今天来写了&#xff0c;unity learn是一个官方教程平台&#xff0c;里面有unity assert store的配套教程&#xff0c;全是文档&#xff0c;比看视…

#java mavn安装图像验证码jar失败kaptcha-2.3.2.jar#

场景&#xff1a;在登录的时候添添加图形验证码功能&#xff0c;使用 com.google.code.kaptcha开发图像验证码&#xff0c;。通过pom引入依赖一直红色提示&#xff0c;找打不到依赖,如图所示 原因&#xff1a;kaptcha-2.3.jar 没有放在mavan的中央仓库 解决方案&#xff0c;需…

Hive笔记

目录 第3章 Hive数据类型 第 4 章 DDL 数据定义 第5章DML数据操作 第6章 查询&#xff08;语法与MySQL一样&#xff09; 第 7 章 分区表和分桶表 第 8 章 函数 第3章 Hive数据类型 如array<map<string,int>> 集合数据类型工作中不是很常用&#xff0c;最常用…

Web 攻防之业务安全:Response状态值修改测试(修改验证码返回值 绕过限制.)

Web 攻防之业务安全&#xff1a;Response状态值修改测试 业务安全是指保护业务系统免受安全威胁的措施或手段。广义的业务安全应包括业务运行的软硬件平台&#xff08;操作系统、数据库&#xff0c;中间件等&#xff09;、业务系统自身&#xff08;软件或设备&#xff09;、业务…

2.17、多生产者-多消费者进程

桌子上有一只盘子&#xff0c;每次只能向其中放入一个水果。爸爸专向盘子中放苹果&#xff0c;妈妈专向盘子中放橘子&#xff0c;儿子专等着吃盘子中的橘子&#xff0c;女儿专等着吃盘子中的苹果。只有盘子空时&#xff0c;爸爸或妈妈才可向盘子中放一个水果。仅当盘子中有自己…

Linux系统应用编程(四)Linux多线程

本篇文章主要内容&#xff1a;Linux系统应用编程&#xff08;四&#xff09;Linux多线程一、线程和进程的区别二、Linux多线程1.线程的使用 - 创建、退出、等待2.线程的同步 - 互斥量&#xff08;1&#xff09;互斥量的理解&#xff08;略&#xff09;&#xff08;2&#xff09…

你真的会自动化测试?自动化测试技术选型抉择

自动化测试框架 在学习自动化测试或者实践自动化测试时&#xff0c;我们一定会对一个名词不陌生&#xff0c;那就是“自动化测试框架”&#xff0c;而有些人也将Selenium、Appium这样的工具也称之为“自动化测试框架”&#xff0c;那么到底自动化测试框架如何理解呢&#xff1…

多种文字翻译软件-翻译常用软件

整篇文档翻译软件 整篇文档翻译软件是一种实现全文翻译的自动翻译工具&#xff0c;它能够快速、准确地将整篇文档的内容翻译成目标语言。与单词、句子翻译不同&#xff0c;整篇文档翻译软件不仅需要具备准确的语言识别和翻译技术&#xff0c;还需要考虑上下文语境和文档格式等多…

【Linux】一文带你探究网络世界的基石

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;计算机网络…

JVM专题

JVM类加载 Java里有如下几种类加载器&#xff1a; 引导类加载器&#xff1a;负责加载支撑JVM运行的位于JRE的lib目录下的核心类库&#xff0c;比如 rt.jar、charsets.jar等 扩展类加载器&#xff1a;负责加载支撑JVM运行的位于JRE的lib目录下的ext扩展目录中的JAR类包应用程序…

一篇文章让你搞懂TypeScript中的??和?:和?.和!.是什么意思

TypeScript中的??和?:和?.和!.是什么意思&#xff1f;知识回调&#xff08;不懂就看这儿&#xff01;&#xff09;场景复现核心干货???:?.!.知识回调&#xff08;不懂就看这儿&#xff01;&#xff09; 知识专栏专栏链接TypeScript知识专栏https://blog.csdn.net/xsl_…

私有化部署GPT,告别网络困扰

最近的GPT是热火朝天&#xff0c;基本人手一个。工具用的好&#xff0c;工作5分钟&#xff0c;划水一整天。 不过最近Chat的访问越来越限制了&#xff0c;访问官网都有网络的问题&#xff0c;今天给大家介绍一个方案&#xff0c;私人独享属于自己的chat&#xff0c;不再担心想…

sdx12使能bluetooth

最后的效果&#xff1a; 1.驱动使能 apps_proc/kernel/msm-5.4/arch/arm/configs/vendor/sdxnightjar.config #add bt driver CONFIG_BTy CONFIG_MSM_BT_POWERy使用的芯片是sdx12 QCA6174A-1 管脚配置如下&#xff08;如果管脚不同&#xff0c;需要修改对应的dts&#xff09…

(十)排序算法-冒泡排序

1 排序算法 1.1 介绍 排序也称为排序算法&#xff08;Sort Algorithm&#xff09;&#xff0c;排序是将一组数据&#xff0c;依指定的顺序进行排列的过程。 1.2 排序的分类 &#xff08;1&#xff09;内部排序 指将需要处理的所有数据都加载到内部存储器中进行排序。 &…

C/C++程序设计——const关键字

1.修饰变量 1.1 作用 功能&#xff1a;不能直接被修改 const修饰变量&#xff0c;就相当于是定义了一个常量。该变量不能直接被修改&#xff0c;但是可以通过指针修改。 作用&#xff1a;便于维护、提前发现可能错误的修改 比如程序中大量使用了一个数字10&#xff0c;且不会…