代码随想录训练营day42| 416. 分割等和子集

news/2025/3/31 11:41:48/

@TOC


前言

代码随想录算法训练营day42


一、Leetcode 416. 分割等和子集

1.题目

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

示例 1:

输入:nums = [1,5,11,5] 输出:true 解释:数组可以分割成 [1, 5, 5] 和 [11] 。

示例 2:

输入:nums = [1,2,3,5] 输出:false 解释:数组不能分割成两个元素和相等的子集。

提示:

1 <= nums.length <= 200
1 <= nums[i] <= 100

来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/partition-equal-subset-sum

2.解题思路

方法一:动态规划

思路与算法

这道题可以换一种表述:给定一个只包含正整数的非空数组 nums[0]nums[0],判断是否可以从数组中选出一些数字,使得这些数字的和等于整个数组的元素和的一半。因此这个问题可以转换成「0−10−1 背包问题」。这道题与传统的「0−10−1 背包问题」的区别在于,传统的「0−10−1 背包问题」要求选取的物品的重量之和不能超过背包的总容量,这道题则要求选取的数字的和恰好等于整个数组的元素和的一半。类似于传统的「0−10−1 背包问题」,可以使用动态规划求解。

在使用动态规划求解之前,首先需要进行以下判断。

根据数组的长度 nn 判断数组是否可以被划分。如果 n<2n<2,则不可能将数组分割成元素和相等的两个子集,因此直接返回 falsefalse。计算整个数组的元素和 sumsum 以及最大元素 maxNummaxNum。如果 sumsum 是奇数,则不可能将数组分割成元素和相等的两个子集,因此直接返回 falsefalse。如果 sumsum 是偶数,则令 target=sum2target=2sum​,需要判断是否可以从数组中选出一些数字,使得这些数字的和等于 targettarget。如果 maxNum>targetmaxNum>target,则除了 maxNummaxNum 以外的所有元素之和一定小于 targettarget,因此不可能将数组分割成元素和相等的两个子集,直接返回 falsefalse。

创建二维数组 dpdp,包含 nn 行 target+1target+1 列,其中 dp[i][j]dp[i][j] 表示从数组的 [0,i][0,i] 下标范围内选取若干个正整数(可以是 00 个),是否存在一种选取方案使得被选取的正整数的和等于 jj。初始时,dpdp 中的全部元素都是 falsefalse。

在定义状态之后,需要考虑边界情况。以下两种情况都属于边界情况。

如果不选取任何正整数,则被选取的正整数等于 00。因此对于所有 0≤i<n0≤i<n,都有 dp[i][0]=truedp[i][0]=true。当 i==0i==0 时,只有一个正整数 nums[0]nums[0] 可以被选取,因此 dp[0][nums[0]]=truedp[0][nums[0]]=true。

对于 i>0i>0 且 j>0j>0 的情况,如何确定 dp[i][j]dp[i][j] 的值?需要分别考虑以下两种情况。

如果 j≥nums[i]j≥nums[i],则对于当前的数字 nums[i]nums[i],可以选取也可以不选取,两种情况只要有一个为 truetrue,就有 dp[i][j]=truedp[i][j]=true。如果不选取 nums[i]nums[i],则 dp[i][j]=dp[i−1][j]dp[i][j]=dp[i−1][j];如果选取 nums[i]nums[i],则 dp[i][j]=dp[i−1][j−nums[i]]dp[i][j]=dp[i−1][j−nums[i]]。如果 j<nums[i]j<nums[i],则在选取的数字的和等于 jj 的情况下无法选取当前的数字 nums[i]nums[i],因此有 dp[i][j]=dp[i−1][j]dp[i][j]=dp[i−1][j]。

状态转移方程如下:

dp[i][j]={dp[i−1][j] ∣ dp[i−1][j−nums[i]],j≥nums[i]dp[i−1][j],j

最终得到 dp[n−1][target]dp[n−1][target] 即为答案。

3.代码实现

```java class Solution { public boolean canPartition(int[] nums) { int n = nums.length; if (n < 2) { return false; } int sum = 0, maxNum = 0; for (int num : nums) { sum += num; maxNum = Math.max(maxNum, num); } if (sum % 2 != 0) { return false; } int target = sum / 2; if (maxNum > target) { return false; } boolean[][] dp = new boolean[n][target + 1]; for (int i = 0; i < n; i++) { dp[i][0] = true; } dp[0][nums[0]] = true; for (int i = 1; i < n; i++) { int num = nums[i]; for (int j = 1; j <= target; j++) { if (j >= num) { dp[i][j] = dp[i - 1][j] | dp[i - 1][j - num]; } else { dp[i][j] = dp[i - 1][j]; } } } return dp[n - 1][target]; } }

```


http://www.ppmy.cn/news/1048262.html

相关文章

centos服务器搭建宝塔面板

因为电脑无线网无法登录宝塔&#xff0c;也无法ssh到服务器&#xff0c;但是热点可以连接&#xff0c;网上没找到解决方法&#xff0c;重装下。 解决办法&#xff0c;先追路由&#xff0c;结果是被防火墙拦截了&#xff0c;解封以后还不行&#xff0c;重新查&#xff0c;联动的…

CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用

CSerialPort教程4.3.x (4) - CSerialPort在QT中的使用 环境&#xff1a; QT: 5.6.3前言 CSerialPort项目是一个基于C/C的轻量级开源跨平台串口类库&#xff0c;可以轻松实现跨平台多操作系统的串口读写&#xff0c;同时还支持C#, Java, Python, Node.js等。 CSerialPort项目…

前端常见的十种布局

前端常见的十种布局方式 若有错误请各位大牛大佬指正&#xff0c;轻喷&#xff01;&#xff01;&#xff01; 前端布局常见的有很多种&#xff0c;不同的应用场景有不同的布局方式&#xff0c;下面就来简单介绍一下吧。 静态布局浮动布局定位布局栅格布局table布局弹性&…

CSS自学框架之动画

这一节&#xff0c;自学CSS动画。主要学习了淡入淡出、淡入缩放、缩放、移动、旋转动画效果。先看一下成果。 优雅的过渡动画&#xff0c;为你的页面添加另一份趣味&#xff01; 在你的选择器里插入 animation 属性&#xff0c;并添加框架内置的 keyframes 即可实现&#xff0…

硕士研究生小论文写作方法

本人985硕博毕业-曾多次辅导本硕同学完成成毕设&#xff0c;下面分享一些经验 图为当年大论文外审结果&#xff01;&#xff01;&#xff01; 当撰写一篇硕士研究生的小论文时&#xff0c;以下是每个部分的写作方法的详细描述&#xff0c;&#xff1a; 摘要&#xff08;Abst…

chrome Dev Tools 性能分析 performance

chrome 的performance用来分析性能优化性能非常好用&#xff0c;下面以一个页面来举例 性能分析 性能分析最好使用隐私无痕模式&#xff0c;以保证干净的环境下&#xff0c;避免chrome插件对性能分析结果的影响 Performance 性能面板 &#xff1a;可看到白屏时间&#xff0c…

点亮一颗LED灯

TOC LED0 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能APB2的外设时钟GPIO_InitTypeDef GPIO_Initstructure;GPIO_Initstructure.GPIO_Mode GPIO_Mode_Out_PP;//通用推挽输出GPIO_Initstructure.GPIO_Pin GPIO_Pin_5;GPIO_Initstructure.GPIO_Speed GPIO_S…

Python学习笔记第六十一天(Matplotlib 绘图标记)

Python学习笔记第六十一天 Matplotlib 绘图标记markerfmt 参数线类型颜色类型标记大小与颜色设置标记外边框颜色自定义标记内部与边框的颜色 后记 Matplotlib 绘图标记 绘图过程如果我们想要给坐标自定义一些不一样的标记&#xff0c;就可以使用 plot() 方法的 marker 参数来定…