代码随想录Day49

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

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数组设置为布尔变量容器,且用到了哈希表来作为字典辅助查询,递推公式的思想也十分巧妙,需要更进一步的理解。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

java 线段树

线段树是一种二叉搜索树&#xff0c;什么叫做二叉搜索树&#xff0c;首先满足二叉树&#xff0c;每个结点度小于等于二&#xff0c;即每个结点最多有两颗子树&#xff0c;何为搜索&#xff0c;我们要知道&#xff0c;线段树的每个结点都存储了一个区间&#xff0c;也可以理解成…

【JavaWeb】8—过滤器

⭐⭐⭐⭐⭐⭐ Github主页&#x1f449;https://github.com/A-BigTree 笔记链接&#x1f449;https://github.com/A-BigTree/Code_Learning ⭐⭐⭐⭐⭐⭐ 如果可以&#xff0c;麻烦各位看官顺手点个star~&#x1f60a; 如果文章对你有所帮助&#xff0c;可以点赞&#x1f44d;…

C语言中宏的一些高级用法举例

C语言中宏的一些高级用法 文章目录C语言中宏的一些高级用法1.字符串化2.标记的拼接3.宏的嵌套替换多条语句防止头文件被重复包含宏的可变参数应用方式1方式2方式34.常用宏宏和函数的区别1.字符串化 #include <stdio.h> #include <stdbool.h> #include <string.…

测试开发常问面试题

Postman Postman实现接口关联 步骤 通过正则表达式或则JSON提取器取值的方式&#xff0c;提取需要的参数。将参数设置为全局变量或则环境变量。在之后接口中&#xff0c;通过{{全局变量/环境变量}}代替要替换的参数值。 - JSON提取器方式 var jsonData JSON.parse(respons…

【Spring6】数据校验:Validation

10、数据校验&#xff1a;Validation 10.1、Spring Validation概述 在开发中&#xff0c;我们经常遇到参数校验的需求&#xff0c;比如用户注册的时候&#xff0c;要校验用户名不能为空、用户名长度不超过20个字符、手机号是合法的手机号格式等等。如果使用普通方式&#xff0c…

TenserRT(三)PYTORCH 转 ONNX 详解

第三章&#xff1a;PyTorch 转 ONNX 详解 — mmdeploy 0.12.0 文档 torch.onnx — PyTorch 2.0 documentation torch.onnx.export 细解 计算图导出方法 TorchScript是一种序列化和优化PyTorch模型的格式&#xff0c;将torch.nn.Module模型转换为TorchScript的torch.jit.Scr…

unicloud 模糊查询解决方案

序 1、where和aggregate的模糊搜索 2、第一种是“你好”去匹配“你好啊大家” 3、第二种是“家啊”去匹配“啊&#xff01;你家呢” 只要有1个字匹配就匹配 4、第三种是“家啊”去匹配“啊&#xff01;你家呢” 必须有“家”又有“啊”才匹配” 想看效果&#xff0c;大家可以自…

ROBOGUIDE教程:FANUC机器人摆焊焊接功能介绍与虚拟仿真操作方法

目录 摆焊功能简介 摆焊指令介绍 摆焊功能设置 摆焊条件设置 机器人摆焊示教编程 仿真运行 摆焊功能简介 使用FANCU机器人进行弧焊焊接时&#xff0c;也可以实现摆动焊接&#xff08;简称摆焊&#xff09;。 摆焊功能是在机器人弧焊焊接时&#xff0c;焊枪面对焊接方向…

面试字节,三面HR天坑,想不到自己也会阴沟里翻船....

阎王易见&#xff0c;小鬼难缠。我一直相信这个世界上好人居多&#xff0c;但是也没想到自己也会在阴沟里翻船。我感觉自己被字节跳动的HR坑了。 在这里&#xff0c;我只想告诫大家&#xff0c;offer一定要拿到自己的手里才是真的&#xff0c;口头offer都是不牢靠的&#xff0…

【CE】Mac下的CE教程Tutorial:进阶篇(第8关:多级指针)

▒ 目录 ▒&#x1f6eb; 导读开发环境1️⃣ 第8关&#xff1a;多级指针翻译操作验证其它方案&#x1f6ec; 文章小结&#x1f4d6; 参考资料&#x1f6eb; 导读 开发环境 版本号描述文章日期2023-03-操作系统MacOS Big Sur 11.5Cheat Engine7.4.3 1️⃣ 第8关&#xff1a;多…

MySQL数据库中的函数怎样使用?

函数 是指一段可以直接被另一段程序调用的程序或代码。 也就意味着&#xff0c;这一段程序或代码在MySQL中已经给我们提供了&#xff0c;我们要做的就是在合适的业务场景调用对应的函数完成对应的业务需求即可。 那么&#xff0c;函数到底在哪儿使用呢? 我们先来看两个场景&a…

【FPGA-Spirit_V2】基于FPGA的循迹小车-小精灵V2开发板

&#x1f389;欢迎来到FPGA专栏~基于FPGA的循迹小车 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;FPGA学习之旅 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望大家能…

Android下载apk并安装apk(用于软件版本升级用途)

软件版本更新是每个应用必不可少的功能&#xff0c;基本实现方案是请求服务器最新的版本号与本地的版本号对比&#xff0c;有新版本则下载apk并执行安装。请求服务器版本号与本地对比很容易&#xff0c;本文就不过多讲解&#xff0c;主要讲解下载apk到安装apk的内容。 一、所需…

Socket套接字编程(实现TCP和UDP的通信)

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

(链表)移除链表元素(双指针法)

文章目录前言&#xff1a;问题描述&#xff1a;解题思路&#xff08;双指针法&#xff09;&#xff1a;代码实现&#xff1a;总结&#xff1a;前言&#xff1a; 此篇是针对链表的经典练习题。 问题描述&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请…

Js:apply/call/bind、作用域/闭包、this指向(普通,箭头,JS/Vue的this)

目录1、apply/call/bind2、作用域、作用域链和闭包核心1、预处理&#xff08;解析阶段&#xff09;——JS执行“代码段”之前2、生成执行上下文环境——对代码段(全局/函数体)进行处理3、执行上下文环境小结4、多个执行上下文环境5、作用域6、作用域和执行上下文7、从【自由变量…

小米万兆路由器里的 Docker 安装 Gitea

小米万兆路由器里的 Docker 安装 Gitea准备工作创建存储查看Docker Hub镜像信息拉取 gitea 镜像和运行容器配置通过 ssh 访问(Optional)其他小米2022年12月份发布了万兆路由器&#xff0c;里面可以使用Docker。 今天尝试在小米的万兆路由器里安装Gitea。 准备工作 先将一块US…

Java企业级开发学习笔记(2.1)MyBatis实现简单查询

该文章主要为完成实训任务&#xff0c;详细实现过程及结果见【http://t.csdn.cn/zi0wB】 文章目录零、创建数据库与表一、基于配置文件方式使用MyBatis基本使用1.1 创建Maven项目 - MyBatisDemo1.2 在pom文件里添加相应的依赖1.3 创建与用户表对应的用户实体类 - User1.4 创建用…

没有他们,人工智能只能死翘翘

我过去写过一篇文章《很多所谓伟大的贡献&#xff0c;其实都是狗屎运》&#xff0c;今天我也写写人工智能。&#xff08;1&#xff09;人才深度神经网络如果不从明斯基和罗森布拉特说起&#xff0c;那就应该可以从1965年Ivakhnenko发明前馈神经网络说起。但关键里程碑是出自Rum…

SpringBoot2核心功能 --- 原理解析

一、Profile功能 为了方便多环境适配&#xff0c;springboot简化了profile功能。 1.1、application-profile功能 默认配置文件 application.yaml&#xff1b;任何时候都会加载指定环境配置文件 application-{env}.yaml激活指定环境配置文件激活 命令行激活&#xff1a;java -…