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

news2024/11/18 16:27:30

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.coloradmin.cn/o/1521574.html

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

相关文章

基于SpringBoot+Vue交流和分享平台的设计与实现(源码+部署说明+演示视频+源码介绍)

您好&#xff0c;我是码农飞哥&#xff08;wei158556&#xff09;&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。&#x1f4aa;&#x1f3fb; 1. Python基础专栏&#xff0c;基础知识一网打尽&#xff0c;9.9元买不了吃亏&#xff0c;买不了上当。 Python从入门到精通…

Android Studio实现内容丰富的安卓宠物用品商店管理系统

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动。 项目编号128 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.系统公告 3.宠物社区&#xff08;可发布宠物帖子&#…

如何将Git拉取项目后,将SSH验证方式修改为HTTPS?

首先在打开项目所在位置的Git BashGUI 查找当前的远程仓库URL&#xff1a; 打开终端或命令提示符&#xff0c;导航到你的项目目录&#xff0c;并使用以下命令查看当前配置的远程仓库URL&#xff1a; git remote -v这会显示如下格式的输出&#xff1a; origin gitgithub.com:用…

从政府工作报告探讨计算机行业的发展

从政府工作报告探计算机行业发展 政府工作报告作为政府工作的全面总结和未来规划&#xff0c;不仅反映了国家整体的发展态势&#xff0c;也为各行各业提供了发展的指引和参考。随着信息技术的快速发展&#xff0c;计算机行业已经成为推动经济社会发展的重要引擎之一。因此&…

什么是 KNIME Hub(2024)

什么是 KNIME Hub KNIME Hub 是一个中央存储库和协作平台&#xff0c;它是用来促进与 KNIME Analytics Platform(分析平台,AP)相关的工作流、节点、组件和扩展的共享和管理。它既充当工作流存储库又充当协作空间&#xff0c;使用户能够发现和利用可合并到其数据分析项目中的各种…

前端Prettier 插件的使用配置(详细)

各个参数代表的意思:printWidth&#xff1a;每行代码的最大长度限制。 tabWidth&#xff1a;选项用于控制制表符的宽度。 useTabs&#xff1a;指定是否使用制表符代替空格。 semi&#xff1a;指定是否在语句的末尾添加分号。 singleQuote&#xff1a;指定是否使用单引号或双引号…

控制学习_正弦波无刷直流力矩电机建模、控制带宽讨论与选择

无刷电机通过电子换向器实现定子的磁场旋转&#xff0c;去电刷后使用寿命大幅提升&#xff0c;是现在更流行的选择。三相无刷电机则是无刷电机中比较流行的一款。三相无刷电机的驱动方式有多种&#xff0c;最简单的被称为梯形波驱动、方波驱动或正弦波驱动。而正弦波驱动技术可…

Redis中的HyperLogLog以及HyperLogLog原理

大家在学习redis的过程中&#xff0c;除了String&#xff0c;list&#xff0c;hash&#xff0c;set&#xff0c;zset这五种基本的数据结构&#xff0c;一定还会接触到几种高级的数据结构&#xff0c;比如bitmap&#xff0c;geo&#xff0c; 还有今天我们要说的hyperloglog&…

【OJ】string类题目

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 1. 415字符串相加1.1 分析1.2 代码 2. 344反转字符串2.1 分析2.2 代码 3. HJ1字符串最后一个单词的长度3.1 分析3.2 代码 4. 387.字符串中的第一个唯一字符4.1 分析4.2 代码 5. 125验证回文串5.1 分析5.2 代码 1. 415字符…

ctf-web23

web23 substr substr:字符串截取&#xff1b;substr()函数可以用于字符串处理、数据清洗、数据挖掘等领域。 substr(abcdef,2,2)返回值cd PHP intval() 函数 ​编辑PHP 可用的函数 intval() 函数用于获取变量的整数值。 intval() 函数通过使用指定的进制 base 转换&…

2000-2021年各省外商直接投资水平面板数据(含原始数据+计算结果)(无缺失)

2000-2021年各省外商直接投资水平面板数据&#xff08;含原始数据计算结果&#xff09;&#xff08;无缺失&#xff09; 1、时间&#xff1a;2000-2021年 2、指标&#xff1a;外商直接投资额&#xff08;万美元&#xff09;、外商直接投资额&#xff08;万元&#xff09;、国…

mysql 更新时,旧值与新值相同会怎么做?

文章目录 1 问题描述2 验证2.1 验证猜想12.2 验证猜想2 3 结论4 mysql 为什么这么设计呢&#xff1f; 1 问题描述 创建一张表t&#xff0c;插入一行数据 mysql> CREATE TABLE t ( id int(11) NOT NULL primary key auto_increment, a int(11) DEFAULT NULL ) ENGINEInnoDB…

01——LenNet网络结构,图片识别

目录 1、model.py文件 &#xff08;预训练的模型&#xff09; 2、train.py文件&#xff08;会产生训练好的.th文件&#xff09; 3、predict.py文件&#xff08;预测文件&#xff09; 4、结果展示&#xff1a; 1、model.py文件 &#xff08;预训练的模型&#xff09; impor…

c语言的字符串函数详解

文章目录 前言一、strlen求字符串长度的函数二、字符串拷贝函数strcpy三、链接或追加字符串函数strcat四、字符串比较函数strcmp五、长度受限制字符函数六、找字符串2在字符串1中第一次出现的位置函数strstr七、字符串切割函数strtok&#xff08;可以切割分隔符&#xff09;八、…

基于springboot实现酒店客房管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现酒店客房管理平台系统演示 摘 要 随着人们的物质水平的提高&#xff0c;旅游业和酒店业发展的速度越来越快。近年来&#xff0c;市面上酒店的数量和规模都在不断增加&#xff0c;如何提高酒店的管理效率和服务质量成为了一个重要的问题。伴随着信息技术的发…

CSS中如何设置单行或多行内容超出后,显示省略号

1. 设置超出显示省略号 css设置超出显示省略号可分两种情况&#xff1a; 单行文本溢出显示省略号…多行文本溢出显示省略号… 但使用的核心代码是一样的&#xff1a;需要先使用 overflow:hidden;来把超出的部分隐藏&#xff0c;然后使用text-overflow:ellipsis;当文本超出时…

mybatis源码阅读系列(一)

源码下载 mybatis 初识mybatis MyBatis 是一个优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射&#xff0c;将接口和 Java 的…

JDK8和JDK11在Ubuntu18上切换(解决nvvp启动报错)

本文主要介绍JDK8和JDK11在Ubuntu18上切换&#xff0c;以供读者能够理解该技术的定义、原理、应用。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;计算机杂记 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人…

docker login 阿里云失败??

docker login 阿里云失败&#xff1f;&#xff1f; 首先参考 阿里云官方文档《Docker登录、推送和拉取失败常见问题》 看看是否是下面提到的情况&#xff1a; 我遇到的情况是超时: [rootk8snode1 software]# sudo docker login --usernametyleryun registry.cn-hangzhou.ali…

sqllab第十八关通关笔记

知识点&#xff1a; UA注入 不进行url解析&#xff0c;不能使用 %20 编码等操作出现在User-agent字段中一般为insert语句 insert 表名(字段1&#xff0c;字段2&#xff0c;。。。) values(数据1&#xff0c;数据2&#xff0c;。。。) 通过admin admin进行登录发现页面打印出了…