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

力扣416:分割等和子集

力扣416:分割等和子集

  • 题目
  • 思路
  • 代码

题目

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

思路

我们先从最简单的思路开始想起,一个数组想要分成两个子集并且子集和相同那么这个数组的和必须是奇数并且数组的大小必须大于2。所以我们可以先对这两个进行判断,其次在求数组和时我们还可以求一下数组的最大元素,然后我们把数组和除2也就得到了两个子集的和target,我们再用子集和和数组的最大元素进行比较,如果最大元素已经大于子集和了也就可以返回false了因为最大元素已经大于子集和了其他的所有元素加起来都不可能等于子集和了。
那么在对特殊情况进行判断也就是剪枝之后我们就可以判断正常情况了,在去掉前面的情况后现在的题目就变成了在数组中是否有一个子序列的序列和为target。在进行问题转换后我们可以来思考一个问题,我们是不是可以把这个问题拆分开来也就是形成一个一个的子问题,那么子问题是什么呢?我们设置i为数组的下标,j为目标值,子问题就是数组的前i个数字是否有一种选法让和为j。那么这个i的范围就是[0,nums.size()),j的范围就是[0,target],所以我们可以定义一个二维数组dp,dp[i][j]就是数组nums的前i个元素是否有一种选择方式可以让和为j,如果有就设为true没有就设为false,有子问题有dp数组这不就是动态规划吗。
在定义了dp数组后我们先来判断边界问题也就是i和j分别为0的情况,当i为0的时说明我们只有一个数字可以选择所以dp[0][nums[0]] = true,当j为0时目标值为0所以无论i为多少我们肯定能得到目标值所以dp[i][0] = true。
在解决了边界问题后我们就要解决普遍情况了,也就是推导状态转移方程即dp[i][j] = ?,我们有两个值可以拿来用一个是当前值nums[i]一个是目标值j,这两个值之间有什么关系吗。当然是有的,如果当前值大于目标值说明这个值不能被选,如果当前值小于目标值说明这个值可以被选也可以不被选,总的来说一个值只有选和被选两种情况。

  1. 被选
    当一个值要被选择时,我们想要判断选上这个数字nums[i]后是否等于j就需要考虑上一个数字nums[i-1]以及目标值j-nums[i]。因为我们选上这个数后前面的子序列的和必须是j-nums[i]。
    所以一个数被选择后
    dp[i][j]=dp[i−1][j−nums[i]]dp[i][j] = dp[i-1][j-nums[i]] dp[i][j]=dp[i1][jnums[i]]
  2. 不被选
    当一个值不被选时我们就只需要考虑前一个数字和当前目标值的是否满足条件了
    dp[i][j]=dp[i−1][j]dp[i][j] = dp[i-1][j] dp[i][j]=dp[i1][j]

所以总的状态转移方程是
dp[i][j]={dp[i−1][j−nums[i]]∣dp[i−1][j](j>=nums[i])dp[i−1][j](j<nums[i])}dp[i][j] = \begin{Bmatrix}dp[i-1][j-nums[i]]| dp[i-1][j] (j >= nums[i]) \\dp[i-1][j](j < nums[i])\end{Bmatrix} dp[i][j]={dp[i1][jnums[i]]dp[i1][j](j>=nums[i])dp[i1][j](j<nums[i])}

代码

class Solution {
public:bool canPartition(vector<int>& nums) {int n = nums.size();if (n < 2) {return false;}int total = 0;int maxnumber = INT_MIN;for (int i = 0; i < n; i++) {total += nums[i];maxnumber = max(maxnumber, nums[i]);}// 数组和为奇数则不可能分为两个子集if (total % 2 != 0) {return false;}int target = total / 2;// 如果最大值小于数组和的一半就说明其他的数加起来也不可能等于最大的数if (maxnumber > target) {return false;}// n行,target+1列// 行代表是数组的前几个数// 列代表的是目标值是多少// dp[i][j]里存储的就是这前几个数有没有可能和为目标值vector<vector<int>> dp(n, vector<int>(target + 1, 0));// 列为0时目标值为0,当然有可能for (int i = 0; i < n; i++) {dp[i][0] = true;}// 行为0时只有一个数可以被选,对应的位置为truedp[0][nums[0]] = true;// 非特殊位置for (int i = 1; i < n; i++) {for (int j = 1; j <= target; j++) {// 判断j和num[i]的大小关系if (j >= nums[i]) {// 如果j大于等于nums[i]就说明这个数字是可以被选也可以不被选的// 被选时dp[i][j]的值就取决于dp[i-1][j-nums[i]]// 不被选dp[i][j]的值取决于dp[i-1][j]dp[i][j] = dp[i - 1][j - nums[i]] | dp[i - 1][j];} else {// j小于nums[i]说明这个值不能被选dp[i][j] = dp[i - 1][j];}}}return dp[n - 1][target];}
};

文章转载自:

http://PMGv75X2.brwwr.cn
http://yRxAhK4e.brwwr.cn
http://UrmjtE43.brwwr.cn
http://lwhr5gZF.brwwr.cn
http://yREwYmiu.brwwr.cn
http://dbm6Yn7x.brwwr.cn
http://zfrYYi58.brwwr.cn
http://wFpsgMJK.brwwr.cn
http://KdslqZN4.brwwr.cn
http://jZVRGBpn.brwwr.cn
http://Ys0XJWMW.brwwr.cn
http://TFS4EGeJ.brwwr.cn
http://93NkGjPM.brwwr.cn
http://ory7wtuS.brwwr.cn
http://4v3lURRu.brwwr.cn
http://6benQ2oQ.brwwr.cn
http://6lZC3gdX.brwwr.cn
http://WhHpiXgC.brwwr.cn
http://9hJGuRIa.brwwr.cn
http://USCcDali.brwwr.cn
http://ScqdfdTE.brwwr.cn
http://Y8FnyRlj.brwwr.cn
http://qp4SRv80.brwwr.cn
http://Gx2F8xtB.brwwr.cn
http://VxueZ91n.brwwr.cn
http://LRQi9Q52.brwwr.cn
http://Og95a4VH.brwwr.cn
http://PxtJqLiF.brwwr.cn
http://znmrQ6TQ.brwwr.cn
http://G04aTPUD.brwwr.cn
http://www.dtcms.com/a/369511.html

相关文章:

  • ATGM336H-5N数据解析说明
  • 2025高中文凭能考的证书大全
  • Windows Server2012 R2 安装.NET Framework 3.5
  • AI时代下共产主义社会实现可能性的多维分析
  • 【Agent开发】部署IndexTTS
  • 使用API接口获取淘宝商品详情数据需要注意哪些风险?
  • 消费品企业客户数据分散?CRM 系统来整合
  • STM32项目分享:面向复杂路段的可控智能交通信号灯设计
  • 【完整源码+数据集+部署教程】加工操作安全手套与手部检测系统源码和数据集:改进yolo11-cls
  • 当洗地机开始「懂你」:VTX316如何让科技更有温度
  • 深度学习模型在边缘计算设备上的部署
  • 【C++题解】贪心和模拟
  • 小学生学习机如何选?AI英语与护眼是关键
  • centos 系统如何安装open jdk 8
  • Git 工具的「安装」及「基础命令使用」
  • PCB 残胶怎么除?猎板分享高效且安全的去除工艺方案
  • 基于FPGA实现数字QAM调制系统
  • 【代码随想录算法训练营——Day2】链表——203.移除链表元素、707.设计链表、206.反转链表
  • GEO公司有哪些:AI时代品牌可见性策略全景分析
  • 迁移学习的案例
  • Linux 入门到精通,真的不用背命令!零基础小白靠「场景化学习法」,3 个月拿下运维 offer,第二十七天
  • 极快文本嵌入推理:Rust构建高性能嵌入推理解决方案
  • 2025国赛C题创新论文+代码可视化 NIPT 的时点选择与胎儿的异常判定
  • MySQL高级进阶(流程控制、循环语句、触发器)
  • JavaScript 源码剖析:从字节码到执行的奇妙旅程
  • 内存纠错检错方法-SSCDSD
  • PostgreSQL收集pg_stat_activity记录的shell工具pg_collect_pgsa
  • AI助力决策:告别生活与工作中的纠结,明析抉择引领明智选择
  • 关于Linux生态的补充
  • 基于cornerstone3D的dicom影像浏览器 第四章 鼠标实现翻页、放大、移动、窗宽窗位调节