【Leetcode】416. 分割等和子集
题目链接:分割等和子集
题目描述:给你一个 只包含正整数 的 非空 数组 nums
。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。
思路:将数组分割成两个等和的子集。
那么:
1)数组元素的和肯定得是偶数,并且数组长度必须大于1。且数组最大值不能大于数组和的一半
2)问题转换为:数组中是否存在若干个元素,其和为数组所有元素和的一半。即寻找若干元素的和为target。
本来的思路是:将元素排序,然后使用回溯的方法,通过了100多个样例。剩下几个样例错误,经过反复思考和尝试发现回溯的方法并不对。
于是看了题解,恍然大悟。
0-1背包问题:
有n个物体和一个背包,将n个物体中的若干个物体放入背包。每个物体只能放1次,即每个物体都是要么放,要么不放。
对应这道题就是,n个物体中选若干个放入一个大小为target的背包,能否刚好装满。
定义一个数组dp[n][target+1],dp[i][j]表示能否从前[0,i]个数中选取若干个使其和刚好为j。最终dp[n-1][target]即为所求。采用了动态规划的思想。
因为每一个物体都可放可不放,所以就有了分类讨论,即得到状态转移方程。
如果j==nums[i],则只放第i个物体即可,即dp[i][j]=true,
如果j<nums[i],则第 i个物体不能放入大小为j的背包里,只能从前[0,i-1]个物体中去取,即dp[i][j]=dp[i-1][j]。
如果j>nums[i],那么第i个物体可以放入大小为j的背包里,也可以选择不放。即dp[i][j]=dp[i-1][j] || dp[i-1][j-nums[i]]
边界条件是:第一列全为false,第一行只有nums[0]对应的值为true。
js代码如下:
var canPartition = function (nums) {const length = nums.length;if (length == 1)return false;let sum = 0;let max=0;for (let num of nums) {sum += num;max=Math.max(max,num);}const target=sum/2;if (sum % 2 == 1)return false;if(max>target)return false;let dp=new Array(length);for(let i=0;i<length;i++){dp[i]=new Array(target+1).fill(false);}dp[0][nums[0]]=true;for(let i=1;i<length;i++){for(let j=1;j<=target;j++){if(j===nums[i])dp[i][j]=true;else if(j<nums[i])dp[i][j]=dp[i-1][j];elsedp[i][j]=dp[i-1][j] || dp[i-1][j-nums[i]];}}return dp[length-1][target];
};
时间复杂度:O(n target),空间复杂度O(n target)
由状态转移方程可知,dp的每一行只和其上一行的数据有关,所以没有必要维护一个二维数组,用一维数组即可。
即dp[j]=dp[j] || dp[j-nums[i]],这里dp[j]和dp[j-nums[i]]都应该是更新之前的数据,所以在对j进行遍历时,应该从后往前,这样保证用到的dp[j-nums[i]]是没有更新过的。若是从前往后,则后面用到dp[j-nums[i]]就是更新过的,导致结果出错。若是从前往后遍历,也可以把dp[j-nums[i]]暂存起来。
js代码如下:
var canPartition = function (nums) {const length = nums.length;if (length == 1)return false;let sum = 0;let max = 0;for (let num of nums) {sum += num;max = Math.max(max, num);}const target = sum / 2;if (sum % 2 == 1)return false;if (max > target)return false;// 一维数组也可以let dp = new Array(target + 1).fill(false);dp[nums[0]] = true;dp[0] = true;for (let i = 1; i < length; i++) {// debuggerfor (let j = target; j >= nums[i]; j--) {dp[j] = dp[j] || dp[j - nums[i]];}}return dp[target];
};
时间复杂度:O(n target),空间复杂度O(target)
【Leetcode】416. 分割等和子集相关推荐
- LeetCode 416 分割等和子集
LeetCode 416 分割等和子集 题目链接 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会 ...
- leetcode - 416. 分割等和子集
416. 分割等和子集 -------------------------------------------- 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和 ...
- LeetCode 416. 分割等和子集 【c++/java详细题解】
来自专栏<LeetCode高频面试题> 欢迎订阅 目录 1.题目 2.思路 3.二维c++代码 4.二维java代码 5.一维优化 6.一维c++代码 7.一维java代码 1.题目 给你 ...
- Java实现 LeetCode 416 分割等和子集
416. 分割等和子集 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: ...
- [动态规划] leetcode 416. 分割等和子集
问题描述: 分割等和子集:给你一个只包含正整数的非空数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 例子:输入nums = {1, 5, 11 , 5 ...
- leetcode 416. 分割等和子集
分割等和子集题解集合 DFS 记忆化搜索 记忆化搜索的另一种写法 动态规划 「滚动数组」解法 「一维空间优化」解法 DFS 思路 题意就是:给你一个非空数组,和为sum,你能否找到一个子序列,和为su ...
- LeetCode 416. 分割等和子集(动态规划)
1. 题目 给定一个只包含正整数的非空数组. 是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [ ...
- LeetCode 416. 分割等和子集(动态规划)(0-1背包)
题目描述 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, ...
- LeetCode #416 分割等和子集
题目: 给你一个 只包含正整数 的 非空 数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 示例 1: 输入:nums = [1,5,11,5] 输出:true ...
- LeetCode | 416.分割等和子集
给你一个 只包含正整数 的 非空 数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 示例 1:输入:nums = [1,5,11,5] 输出:true 解释:数组 ...
最新文章
- WMI技术介绍和应用——查询正在运行的进程信息
- MongoDB系列:五、MongoDB Driver使用正确的姿势连接复制集
- [错误记录] --- rocketmq批量消费设置参数的问题
- Recipe terminated with error. vscode latex-workshop新的配置文件
- java核心面试_前100多个核心Java面试问题
- 在 RHEL 和 CentOS 上检查或列出已安装的安全更新的两种方法
- 周立功上位机获取CAN通讯数据解析 V2.0
- RANSAC算法——看完保证你理解
- 如何设计一款智能烧烤锅?
- linux win10虚拟内存,Win10虚拟内存设置多少合适?这样设置就最好!
- netbeans php下载,Netbeans7下载和安装
- DfE给学生提供的笔记本电脑感染了恶意软件
- 什么是Python?Python简介
- 【写着玩】二维码检测及定位
- 撩小姐姐的小程序(二)----旋转3D八音盒
- Linux 音频驱动(一) ASoC音频框架简介
- 沈阳大雨部分地区积水情况
- 我的世界服务器怎么弄领地语言,我的世界领地指令权限大全 我的世界领地指令设置教程...
- java connect four_JAVA connectFour
- 语义化的理解:有哪些语义化标签?有什么作用?
热门文章
- Parcel Bundle漏洞学习
- 教育部高等学校大学计算机课程教学指导委员会,2018-2022教育部高等学校工科基础课程教学指导委员会2018年全体委员会议在北京召开...
- 区块链应用 | 泡沫之下的区块链
- 汇编语言 实现1.将数据区buf1中的10个数,传送到数据区buf2 2.计算buf1数据的累加和
- (附源码)node.js华联招聘网站 毕业设计 011229
- 外刊IT网站经典计算机开发,评论,总结文章汇总共享
- 深度解读 | 从Gartner SIEM魔力象限报告看安全运营的门道
- WEBDisk网络硬盘
- c语言算法:排队打饭
- 算法模型好坏、评价标准、算法系统设计