代码随想录算法训练营Day44|322.零钱兑换、279.完全平方数、139.单词拆分

本文主要是介绍代码随想录算法训练营Day44|322.零钱兑换、279.完全平方数、139.单词拆分,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

零钱兑换

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

本题是完全背包问题

dp数组表示组成amount金额所需的最少硬币个数。

考虑dp数组的推导公式,由于是计算最少硬币的个数,所以需要考虑dp[i-coins[j]+1和dp[i]的较小值。所以dp[i] = min(dp[i-coins[j]]+1,dp[i]),其中i为遍历过程中的amout值,coins[j]为硬币的面值。

已知推导公式,我们需要对dp数组赋值,由于dp推导式中求的是较小值,所以我们设定dp[0] = 0,其余值都为INT_MAX。

之后是对dp数组的遍历顺序,这里由于我们考虑的是最少银币个数,并不在乎排列或是组合的情况(组成的数目),所以对背包或是物品进行遍历都是可以的,这里我使用先背包后物品的遍历方式。

class Solution {
public:int coinChange(vector<int>& coins, int amount) {// 创建一个动态规划数组dp,大小为amount+1,初始化为INT_MAX(表示无法凑成的金额)vector<int>dp(amount+1,INT_MAX);// 找零0元需要0个硬币dp[0] = 0;// 遍历从1到amount的每一个金额for(int i = 1; i<=amount;i++){// 遍历每一种硬币for(int j = 0;j<coins.size();j++){// 如果当前金额大于或等于当前硬币面额,并且当前金额减去当前硬币面额的找零方式存在if(i-coins[j]>=0 and dp[i-coins[j]]!=INT_MAX){// 更新当前金额的最少硬币数量为min(当前最少硬币数量, 减去当前硬币面额的金额的硬币数量+1)dp[i] = min(dp[i],dp[i-coins[j]]+1);}}}// 如果amount的找零方式不存在,返回-1if(dp[amount] == INT_MAX)return -1;// 返回amount的最少硬币找零数量return dp[amount];}
};

算法的时间复杂度为O(n*m),n为coins数组的长度,m为amount+1,空间复杂度为O(m),需要维护一个dp数组,长度为amount+1.

完全平方数

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

感觉本题和上题比较类似,唯一的不同在于coins数组需要我们自己获取。

dp数组定义等都和上题相同。

class Solution {
public:int numSquares(int n) {// 创建一个动态规划数组dp,大小为n+1,初始化为INT_MAX(表示无法组成的情况)vector<int> dp(n+1, INT_MAX);// 创建一个数组T_S_N,用于存储小于等于n的所有完全平方数vector<int> T_S_N; // total Square numbers// 计算小于等于n的所有完全平方数并存储到T_S_N中for (int i = 1; i * i <= n; i++) {T_S_N.push_back(i * i);}// 组成0需要0个完全平方数dp[0] = 0;// 遍历从1到n的每一个金额for (int i = 1; i <= n; i++) {// 遍历每一种完全平方数for (int j = 0; j < T_S_N.size(); j++) {// 如果当前数值大于或等于当前完全平方数,并且当前数值减去当前完全平方数的组成方式存在if (i - T_S_N[j] >= 0 && dp[i - T_S_N[j]] != INT_MAX) {// 更新当前数值的最少完全平方数数量为min(当前最少完全平方数数量, 减去当前完全平方数的金额的完全平方数数量+1)dp[i] = min(dp[i - T_S_N[j]] + 1, dp[i]);}}}// 返回n的最少完全平方数组成数量return dp[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++) { // 遍历背包dp[j] = min(dp[j - i * i] + 1, dp[j]);}}return dp[n];}
};

算法的时间复杂度为O(n*(3/2)),空间复杂度为O(n)。

单词拆分

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

具体参考代码随想录 代码随想录 (programmercarl.com)。

考虑单词为物品,所要匹配的字符串为背包,单词可以重复使用,就是一个使用单词匹配字符串(单词是否能完全构成字符串)的完全背包问题。

这里我们考虑将单词数组存入哈希集合,因为可以方便快速寻找

dp[i]中i表示字符串的长度,dp[i]表示为是否可以拆分为单词数组中的单词,值为true 或false.

dp[i]的递推公式我们应这样考虑,若dp[before_i]为true,且before_i至i的位置的字符串存在于单词数组中,则dp[i]为true,否则为false。

考虑到dp[i]取决于前面的值,则dp[0] = true,否则后续值递推全为false。

遍历方式:这里需注意应为排列,每个单词元素的顺序是有意义的。因此考虑先背包后物品的遍历方式

最后返回数组的末尾元素即知道拆分是否可能实现。

class Solution {
public:bool wordBreak(string s, vector<string>& wordDict) {// 创建一个哈希集合word_set,用于存储wordDict中的所有单词,以便快速查找unordered_set<string> word_set{};// 将wordDict中的所有单词插入到word_set中for (auto word : wordDict) {word_set.insert(word);}// 创建一个动态规划数组dp,大小为s.size()+1,初始化为false// dp[i]表示字符串s的前i个字符是否可以被拆分成wordDict中的单词vector<bool> dp(s.size() + 1, false);// 初始化dp[0]为true,因为空字符串可以被拆分成空集合dp[0] = true;// 遍历字符串s的每一个位置for (int i = 1; i <= s.size(); i++) {// 对于每个位置i,尝试从0到i的所有分割点jfor (int j = 0; j < i; j++) {// 取出从j到i的子串string word = s.substr(j, i - j);// 如果子串word在word_set中,并且dp[j]为true(前j个字符可以拆分)if (word_set.find(word) != word_set.end() && dp[j]) {// 则dp[i]为true,表示前i个字符可以拆分dp[i] = true;}}}// 返回dp[s.size()]return dp[s.size()];}
}; 
  • 时间复杂度:O(n^3),因为substr返回子串的副本是O(n)的复杂度(这里的n是substring的长度)
  • 空间复杂度:O(n)

这篇关于代码随想录算法训练营Day44|322.零钱兑换、279.完全平方数、139.单词拆分的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


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

相关文章

深入解析 Java Future 类及代码示例

《深入解析JavaFuture类及代码示例》JavaFuture是java.util.concurrent包中用于表示异步计算结果的核心接口,下面给大家介绍JavaFuture类及实例代码,感兴... 目录一、Future 类概述二、核心工作机制代码示例执行流程2. 状态机模型3. 核心方法解析行为总结:三

python获取cmd环境变量值的实现代码

《python获取cmd环境变量值的实现代码》:本文主要介绍在Python中获取命令行(cmd)环境变量的值,可以使用标准库中的os模块,需要的朋友可以参考下... 前言全局说明在执行py过程中,总要使用到系统环境变量一、说明1.1 环境:Windows 11 家庭版 24H2 26100.4061

pandas实现数据concat拼接的示例代码

《pandas实现数据concat拼接的示例代码》pandas.concat用于合并DataFrame或Series,本文主要介绍了pandas实现数据concat拼接的示例代码,具有一定的参考价值,... 目录语法示例:使用pandas.concat合并数据默认的concat:参数axis=0,join=

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

Python使用Code2flow将代码转化为流程图的操作教程

《Python使用Code2flow将代码转化为流程图的操作教程》Code2flow是一款开源工具,能够将代码自动转换为流程图,该工具对于代码审查、调试和理解大型代码库非常有用,在这篇博客中,我们将深... 目录引言1nVflRA、为什么选择 Code2flow?2、安装 Code2flow3、基本功能演示

IIS 7.0 及更高版本中的 FTP 状态代码

《IIS7.0及更高版本中的FTP状态代码》本文介绍IIS7.0中的FTP状态代码,方便大家在使用iis中发现ftp的问题... 简介尝试使用 FTP 访问运行 Internet Information Services (IIS) 7.0 或更高版本的服务器上的内容时,IIS 将返回指示响应状态的数字代

MySQL 添加索引5种方式示例详解(实用sql代码)

《MySQL添加索引5种方式示例详解(实用sql代码)》在MySQL数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中,下面给大家分享MySQL添加索引5种方式示例详解(实用sql代码),... 在mysql数据库中添加索引可以帮助提高查询性能,尤其是在数据量大的表中。索引可以在创建表时定义,也可

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

Python实现一键PDF转Word(附完整代码及详细步骤)

《Python实现一键PDF转Word(附完整代码及详细步骤)》pdf2docx是一个基于Python的第三方库,专门用于将PDF文件转换为可编辑的Word文档,下面我们就来看看如何通过pdf2doc... 目录引言:为什么需要PDF转Word一、pdf2docx介绍1. pdf2docx 是什么2. by

Spring Security介绍及配置实现代码

《SpringSecurity介绍及配置实现代码》SpringSecurity是一个功能强大的Java安全框架,它提供了全面的安全认证(Authentication)和授权(Authorizatio... 目录简介Spring Security配置配置实现代码简介Spring Security是一个功能强