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

day38 力扣279.完全平方数 力扣322. 零钱兑换 力扣139.单词拆分

完全平方数

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

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

示例 1:

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

示例 2:

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

提示:

  • 1 <= n <= 104

一看可以重复使用,那就是完全背包的问题,后续外层for循环遍历背包容量,内层遍历物品。

因为本题所求的是最少的完全平方数量,dp[j]表示容量为j的背包需要的最少完全平方数量。

那么,我们在初始化的时候,需要把dp初始化的尽可能大,也就是每个dp[j]=j(即每个都是由j个1*1组成)。

还有一个问题,就是遍历的物品是什么呢? 等同于j嘛? 其实并不是,i<=sqrt(j)也就是根号下容量才是我们的物品,因为我们所求的是完全平方。

如果当前容量j>=i*i,那我们就让dp[j]等于 dp[j]和 dp[j-i*i]+1的最小值。

class Solution {
public:int numSquares(int n) {vector<int> dp(n+1);for(int i = 0;i <= n;i++){dp[i] = i;}for(int j = 0;j<=n;j++){for(int i = 1;i<=sqrt(n);i++){if(j>=i*i) dp[j] = min(dp[j],dp[j-i*i]+1);}}return dp[n];}
};

 零钱兑换

给你一个整数数组 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

其实这道题应该是在完全平方数前面的,但是我做反了······

但我觉得这道题比完全平方数更难(因为完全平方数我做出来了,这道题自己没做出来)。

这道题我认为比较难的地方就是初始化,首先都初始化为-1,我的想法是,两层循环,外层遍历物品,内层遍历背包,只考虑使用同一种物品,如果能塞满背包,dp[j] = j/coins[i]。

得到如下代码:

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1,-1);for(int i = 0;i<coins.size();i++){for(int j = 0;j<=amount;j++){if(j%coins[i]==0&&dp[j]!=-1) dp[j] =min(dp[j],j/coins[0]);else if(j%coins[i]==0&&dp[j]==-1) dp[j] =j/coins[0];}}for(int j = 0;j<=amount;j++){for(int i = 0;i<coins.size();i++){if(j>=coins[i]&&dp[j-coins[i]!=-1]) dp[j] = min(dp[j],dp[j-coins[i]]+1);}}return dp[amount];}
};

 但是并不太可取(WA,我不知道怎么改了)。

下面给出题解方法:

在初始化时,我们初始化为INT_MAX,dp[0]=0。

循环内,如果dp[j-coins[i]] == INT_MAX就不处理,反之就让dp[j] = min(dp[j],dp[j-coins[i]]+1);

最后如果dp[amount]== INT_MAX ,就return -1 ,如果不是,就return dp[amount]。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount+1,INT_MAX);dp[0] = 0;for(int j = 1;j<=amount;j++){for(int i = 0;i<coins.size();i++){if(j>=coins[i]&&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];}
};

单词拆分

给你一个字符串 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 中的所有字符串 互不相同

一看可以重复使用,那就是完全背包的问题,后续外层for循环遍历背包容量,内层遍历物品。

dp[j]表示s从0到j位置的子字符串是否可以用字典符里的word表示。

初始化dp[0]为true,其他均为false。

j表示容量,i在0和j之间,如果i到j的字符串在字典中出现,且dp[i]==true,那dp[j]也是true。

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {vector<bool> dp(s.size()+1,false);unordered_set<string> wordSet(wordDict.begin(),wordDict.end());dp[0] = true;for(int j = 1;j<=s.size();j++){for(int i = 0;i<j;i++){string word = s.substr(i,j-i);if(wordSet.find(word)!=wordSet.end()&&dp[i])dp[j] = true;}}return dp[s.size()];}
};

将 wordDict 转换为 unordered_set 是为了提高查找效率。 unordered_set 内部使用哈希表实现,平均时间复杂度为 O(1) 进行元素的插入、删除和查找操作。而 vector 的查找操作(例如使用 std::find )需要遍历整个 vector ,平均时间复杂度为 O(n),其中 n 是 vector 的大小。在 wordBreak 这种需要频繁查找单词的场景中,使用 unordered_set 可以显著提升性能。

http://www.xdnf.cn/news/1228339.html

相关文章:

  • python---literal_eval函数
  • 轨道追逃博弈仿真
  • Node.js 路由与中间件
  • StarRocks vs ClickHouse:2025 年 OLAP 引擎终极对比指南
  • 高效截图的4款工具深度解析
  • cmd怎么取消关机命令
  • Oracle 11g RAC集群部署手册(二)
  • C语言(长期更新)第7讲:VS实用调试技巧
  • 仿真电路:(十七下)DC-DC升压压电路原理简单仿真
  • 【DL学习笔记】计算图与自动求导
  • 鸿蒙智选携手IAM进驻长隆熊猫村,为国宝打造智慧健康呼吸新空间
  • [硬件电路-120]:模拟电路 - 信号处理电路 - 在信息系统众多不同的场景,“高速”的含义是不尽相同的。
  • C语言字符函数和字符串函数全解析:从使用到模拟实现
  • [硬件电路-115]:模拟电路 - 信号处理电路 - 功能放大器工作分类、工作原理、常见芯片
  • 深入 Go 底层原理(十一):Go 的反射(Reflection)机制
  • stm32是如何实现电源控制的?
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频摘要生成与智能检索优化进阶(377)
  • QT中使用OpenCV保姆级教程
  • 搜索与图论(最小生成树 二分图)
  • MyBatisPlus之核心注解与配置
  • Docker 部署与配置 MySQL 5.7
  • 位运算-371.两整数之和-力扣(LeetCode)
  • 解决 InputStream 只能读取一次问题
  • 【多模态】DPO学习笔记
  • [创业之路-528]:技术成熟度曲线如何指导创业与投资?
  • Python爬虫实战:研究mahotas库,构建图像获取及处理系统
  • 【DeepSeek-R1 】分词系统架构解析
  • 社群团购市场选择与开源技术赋能下的下沉市场开拓策略研究——以开源AI智能名片、链动2+1模式与S2B2C商城小程序为例
  • LLM Prompt与开源模型资源(3)如何写一个好的 Prompt
  • 【论文笔记】Multi-Behavior Graph Neural Networks for Recommender System