当前位置: 首页 > 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.dtcms.com/a/311822.html

相关文章:

  • 位运算-371.两整数之和-力扣(LeetCode)
  • 2 安装 Docker 和 Jenkins:持续构建环境起步
  • Chisel芯片开发入门系列 -- 17. CPU芯片开发和解释7(5级流水线指令原理)
  • 洛谷 P3372 【模板】线段树 1-普及+/提高
  • 【AI学习】RadioDiff:代码学习
  • Paper Reading《TrafficFormer: An Efficient Pre-trained Model for Traffic Data》
  • 【MQ】kafka同步和异步的区别
  • Windows中使用Qwen模型:VSCode+Cline
  • 64GB U盘实际显示容量为57.2GB的原因解析
  • innoDB的buffer pool
  • Wasatch SoftRIP数码打印 印花软件
  • 谷歌开源Agent框架ADK快速入门
  • 深入理解 Go 语言中 Map 的底层原理
  • Python爬虫实战:研究SimpleCV技术,构建图像获取及处理系统
  • Apache Doris数据库——大数据技术
  • 【LeetCode刷题指南】--二叉树的前序遍历,二叉树的中序遍历
  • MCP Agent 工程框架Dify初探
  • pytorch简单理解
  • 我的世界之战争星球 暮色苍茫篇 第二十六章、身世
  • 分布在内侧内嗅皮层的层Ⅱ或层Ⅲ的头部方向细胞(head direction cells)对NLP中的深层语义分析的积极影响和启示
  • JVM中年轻代、老年代、永久代(或元空间)、Eden区和Survivor区概念介绍
  • Mysql insert 语句
  • 入门MicroPython+ESP32:开启科技新旅程
  • 机试备考笔记 2/31
  • FastAPI--一个快速的 Python Web
  • C++ 自定义简单的异步日志类
  • oect刷入arm系统安装docker
  • Python深度学习:从入门到精通
  • retro-go 1.45 编译及显示中文
  • 联合索引全解析:一棵树,撑起查询的半边天