力扣hot100:416.分割等和子集(组合/动态规划/STL问题)

893a7603c38744d3a8d19eb2d79e5588.png

组合数问题

我们思考一下,如果要把数组分割成两个子集,并且两个子集的元素和相等,是否等价于在数组中寻找若干个数使之和等于所有数的一半?是的!

因此我们可以想到,两种方式:

①回溯的方式找到target,但是回溯是阶乘级别的算法,这里会超时。

②从前往后遍历,形象说明:定义n个集合dp[i],dp[i]表示前i个数的可能组合值,则有dp[i]={dp[i-1],dp[i-1]+i},dp[i-1]+i指的是i加上dp[i-1]中的所有元素得到的集合。同时由于长度最长200,数值最大为100,因此数的范围最大为1<=i<=20000,因此最多只有20000个不同的数。因此dp最大为2W个数!所以我们可以用集合实现,并且时间复杂度满足要求O(nums.length*nums.length*max(nums[i]))!

class Solution {
public:bool canPartition(vector<int>& nums) {int sum=0;for(auto &i:nums) sum+=i;if(sum&1||nums.size()==1) return false;//只有偶数总和可以sum>>=1;unordered_set<int> Set;vector<int> temp;for(auto &i:nums){if(i==sum) return true;for(auto it=Set.cbegin();it!=Set.cend();++it){int cur=*it+i;if(cur==sum) return true;if(cur<sum) temp.emplace_back(cur);//>sum的没意义}for(auto & j:temp) Set.insert(j);temp.clear();Set.insert(i);}return false;}
};

遇到的问题:

        在循环遍历的过程中往容器中插入元素会导致容器迭代器end()和size(),时刻发生变化。与此同时,有的容器比如vector和string,往后面增加元素超过容量capacity可能会导致拷贝,从而整个迭代器失效。因此!在使用循环并且需要添加元素时,想使用迭代器需要额外注意!

比如本题是先将所需增加的放入到一个vector中的。

我们不能企图使用临时“指针”迭代器i=end(),然后遍历到it!=i,这是错误的!因为i一直指向的仍然是end(),而不是end()当时指向的位置,换句话说end()不是一个具体的位置,而是一个抽象的位置。

int tmp=Set.size();
for(auto it=Set.cbegin();tmp!=0;++it,--tmp){ int cur=*it+i;if(cur==sum) return true;temp.emplace_back(cur);Set.insert(cur);
}

这样做仍然是错误的,实际上我们在往非顺序容器中插入元素时,容器的数据结构会发生变化,因此导致++it可能并非按照原来的想法遍历,所以是错误的!

唯一正确且安全的方式是,如果需要在遍历的时候同时添加元素,最好不要使用迭代器!迭代器可以很好的遍历元素或者按迭代器范围赋值。但是边添加边遍历问题非常大。

因此对于无序容器只能使用迭代器的情况下,使用临时容器存储是非常必要的;对于顺序容器可以使用下标的情况下,使用下标更好。

动态规划

        这道题实际上和0-1背包问题很像,即从n个物品中拿出一部分使得其值刚好等于target。意识到这一点我们可以定义动态转移方程:

dp[i][k]=max(dp[i-1][k-nums[i]],dp[i-1][k]);

dp[0][nums[0]]=1;

//dp[i][k]表示拿前i个物品是否可以达到重量k。

        这实际上和方法一组合数问题是异曲同工的,方法一使用集合实现,那么如果方法一使用的是数组实现呢?那么数组中标记为1的实际上就是方法二的状态了!

class Solution {
public:bool canPartition(vector<int>& nums) {int sum=0;for(auto &i:nums) sum+=i;if(sum&1||nums.size()==1) return false;sum>>=1;vector<vector<int>> dp(nums.size(),vector<int>(sum+1,0));//超过sum实际上就不用看了if(nums[0]<=sum)dp[0][nums[0]]=1;for(int i=1;i<nums.size();++i){for(int j=1;j<=sum;++j){dp[i][j]=dp[i-1][j];if(j-nums[i]>=0)dp[i][j]=max(dp[i-1][j-nums[i]],dp[i-1][j]);}if(nums[i]<=sum)dp[i][nums[i]]=1;}return dp[nums.size()-1][sum];}
};

由于只用到前面的值,很显然我们可以降维优化。

class Solution {
public:bool canPartition(vector<int>& nums) {int sum=0;for(auto &i:nums) sum+=i;if(sum&1||nums.size()==1) return false;sum>>=1;vector<int> dp(sum+1,0);//超过sum实际上就不用看了if(nums[0]<=sum)dp[nums[0]]=1;for(int i=1;i<nums.size();++i){for(int j=sum;j>=nums[i];--j){dp[j]=max(dp[j],dp[j-nums[i]]);}}return dp[sum];}
};

 

 

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

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

相关文章

vanna:基于RAG的text2sql框架

文章目录 vanna简介及使用vanna的原理vanna的源码理解总结参考资料 vanna简介及使用 vanna是一个开源的利用了RAG的SQL生成python框架&#xff0c;在2024年3月已经有了5.8k的star数。 Vanna is an MIT-licensed open-source Python RAG (Retrieval-Augmented Generation) fram…

探讨大世界游戏的制作流程及技术——大场景制作技术概况篇

接上文&#xff0c;我们接下来了解一下大世界场景制作技术有哪些&#xff0c;本篇旨在给大家过一遍目前业界的做法&#xff0c;能让大家有一个宏观的知识蓝图。实际上&#xff0c;针对不同的游戏类型和美术风格&#xff0c;制作技术在细节上有着非常大的不同&#xff0c;业界目…

逗号运算符

在C语言中&#xff0c;逗号运算符,用于分隔表达式&#xff0c;并按顺序计算每个表达式&#xff0c;最终返回最后一个表达式的值。逗号运算符的语法如下&#xff1a; expression1, expression2它的行为是先计算expression1&#xff0c;然后计算expression2&#xff0c;最后返回e…

Meson编译工具安装及使用Meson编译DPDK

一、Meson编译工具安装 1&#xff09;安装python3的环境 yum install -y python3 python3 -m ensurepip --upgrade 2&#xff09;安装meson pip3 install --user meson --default-timeout10000 export PATH$PATH:$HOME/.local/bin使得环境变量一直有效&#xff0c;可编辑 /etc/…

HarmonyOS NEXT应用开发—自定义视图实现Tab效果

介绍 本示例介绍使用Text、List等组件&#xff0c;添加点击事件onclick,动画&#xff0c;animationTo实现自定义Tab效果。 效果预览图 使用说明 点击页签进行切换&#xff0c;选中态页签字体放大加粗&#xff0c;颜色由灰变黑&#xff0c;起到强调作用&#xff0c;同时&…

手撕算法-队列实现栈And栈实现队列

手撕算法-队列实现栈And栈实现队列 两个栈实现队列两个队列实现栈包含min函数的栈 两个栈实现队列 分析&#xff1a;转换数据方向&#xff0c;第一个栈写&#xff0c;第二个栈读。 代码&#xff1a; import java.util.*; import java.util.Stack;public class Solution {Sta…

2789. 合并后数组中的最大元素

2789. 合并后数组中的最大元素 题目链接&#xff1a;2789. 合并后数组中的最大元素 代码如下&#xff1a; //贪心&#xff0b;倒叙数组 //参考leetcode官方题解 class Solution { public:long long maxArrayValue(vector<int>& nums) {long long sumnums[nums.size…

PyCharm中如何使用不同的虚拟环境

1. 简介 有些项目用老的运行环境&#xff0c;而有些项目用新的运行环境&#xff0c;那么我们在运行这些代码&#xff08;比如跑对比实验的时候&#xff09;如何进行切换呢&#xff0c;这时候就可以使用虚拟环境啦 2. 虚拟环境的创建 首先启动Anaconda Prompt 并在其中执行如…

ubuntu 开发软件安装

jdk tar -zxvf jdk-8u311-linux-x64.tar.gz jdk1.8.0_311/-- /etc/profile export JAVA_HOME=/opt/java/jdk1.8.0_311 export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH

调皮的String及多种玩法(下部)

&#x1f468;‍&#x1f4bb;作者简介&#xff1a;&#x1f468;&#x1f3fb;‍&#x1f393;告别&#xff0c;今天 &#x1f4d4;高质量专栏 &#xff1a;☕java趣味之旅 欢迎&#x1f64f;点赞&#x1f5e3;️评论&#x1f4e5;收藏&#x1f493;关注 &#x1f496;衷心的希…

LeetCode 面试经典150题 26.删除有序数组中的重复项

题目&#xff1a; 给你一个 非严格递增排列 的数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使每个元素 只出现一次 &#xff0c;返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。 考虑 nums 的唯一元素的数量…

C# SM2加解密 ——国密SM2算法

SM2 是国家密码管理局组织制定并提出的椭圆曲线密码算法标准。 本文使用第三方密码库 BouncyCastle 实现 SM2 加解密&#xff0c;使用 NuGet 安装即可&#xff0c;包名&#xff1a;Portable.BouncyCastle&#xff0c;目前最新版本为&#xff1a;1.9.0。 using Org.BouncyCastl…

相机sd卡照片删除后数据恢复,相机sd卡中的照片被删除后如何恢复数据

当我们使用相机拍摄照片时&#xff0c;有时会不小心删除了一些重要的照片。这可能是因为误操作、SD卡故障或者其他原因。无论是珍贵的照片、还是重要的工作文件&#xff0c;被删除后&#xff0c;我们往往会感到焦虑和失望。相机sd卡中的照片被删除后如何恢复数据&#xff1f;幸…

Java项目:54 springboot工资信息管理系统453

作者主页&#xff1a;源码空间codegym 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 本系统的使用角色可以被分为用户和管理员&#xff0c; 用户具有注册、查看信息、留言信息等功能&#xff0c; 管理员具有修改用户信息&#…

洛谷P1097 [NOIP2007 提高组] 统计数字

#先看题目 题目描述 某次科研调查时得到了 n 个自然数&#xff0c;每个数均不超过 1.5109。已知不相同的数不超过 个&#xff0c;现在需要统计这些自然数各自出现的次数&#xff0c;并按照自然数从小到大的顺序输出统计结果。 输入格式 共 n1 行。 第一行是整数 n&#x…

24年三月周末总结

工作 我在工作上有一个毛病&#xff0c;就是不能很好的控制精力和情绪&#xff0c;我需要学习精力管理和情绪管理。 目前工作不会有什么起色&#xff0c;计划今年7月份&#xff08;全栈工程师&#xff09;转移到成都。 精力管理 可以在B站查阅这个视频进行学习精力管理 学习…

函数返回二维数组

在C语言中&#xff0c;函数不能直接返回二维数组&#xff0c;因为数组名作为函数参数或返回值时&#xff0c;会退化为指向数组首元素的指针。此外&#xff0c;C语言不支持返回局部数组的引用&#xff0c;因为局部数组在函数返回后其内存会被释放。 1. 使用动态内存分配&#…

Kafka-SSL笔记整理

创建密钥仓库以及CA 创建密匙仓库,用户存储证书文件keytool -keystore server.keystore.jks -alias hello_kafka -validity 100000 -genkey创建CAopenssl req -new -x509 -keyout ca-key -out ca-cert -days 100000将生成的CA添加到客户端信任库keytool -keystore client.trus…

SPI驱动分析之二

三、主控制器的驱动注册 文件spi_imx.c中 subsys_initcall(spi_imx_init); static int __init spi_imx_init(void) { return platform_driver_register(&spi_imx_driver); } static struct platform_driver spi_imx_driver { .driver { .name DR…

InfluxDB下载安装教程

InfluxDB下载安装教程 一、简介二、【linux】InfluxDB下载安装配置2.1 下载安装2.1.1 apt在线安装2.1.2 离线安装 2.2 配置及启动 3、windows 下的安装方式4、InfluxDB基本使用4.1 创建用户4.2 数据库 回到目录 一、简介 InfluxDB是一个由InfluxData开发的开源时序型数据库。它…