题目链接:分割等和子集

题目描述:给你一个 只包含正整数非空 数组 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. 分割等和子集相关推荐

  1. LeetCode 416 分割等和子集

    LeetCode 416 分割等和子集 题目链接 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会 ...

  2. leetcode - 416. 分割等和子集

    416. 分割等和子集 -------------------------------------------- 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和 ...

  3. LeetCode 416. 分割等和子集 【c++/java详细题解】

    来自专栏<LeetCode高频面试题> 欢迎订阅 目录 1.题目 2.思路 3.二维c++代码 4.二维java代码 5.一维优化 6.一维c++代码 7.一维java代码 1.题目 给你 ...

  4. Java实现 LeetCode 416 分割等和子集

    416. 分割等和子集 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: ...

  5. [动态规划] leetcode 416. 分割等和子集

    问题描述:    分割等和子集:给你一个只包含正整数的非空数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等.   例子:输入nums = {1, 5, 11 , 5 ...

  6. leetcode 416. 分割等和子集

    分割等和子集题解集合 DFS 记忆化搜索 记忆化搜索的另一种写法 动态规划 「滚动数组」解法 「一维空间优化」解法 DFS 思路 题意就是:给你一个非空数组,和为sum,你能否找到一个子序列,和为su ...

  7. LeetCode 416. 分割等和子集(动态规划)

    1. 题目 给定一个只包含正整数的非空数组. 是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [ ...

  8. LeetCode 416. 分割等和子集(动态规划)(0-1背包)

    题目描述 给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 注意: 每个数组中的元素不会超过 100 数组的大小不会超过 200 示例 1: 输入: [1, ...

  9. LeetCode #416 分割等和子集

    题目: 给你一个 只包含正整数 的 非空 数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 示例 1: 输入:nums = [1,5,11,5] 输出:true ...

  10. LeetCode | 416.分割等和子集

    给你一个 只包含正整数 的 非空 数组 nums .请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等. 示例 1:输入:nums = [1,5,11,5] 输出:true 解释:数组 ...

最新文章

  1. WMI技术介绍和应用——查询正在运行的进程信息
  2. MongoDB系列:五、MongoDB Driver使用正确的姿势连接复制集
  3. [错误记录] --- rocketmq批量消费设置参数的问题
  4. Recipe terminated with error. vscode latex-workshop新的配置文件
  5. java核心面试_前100多个核心Java面试问题
  6. 在 RHEL 和 CentOS 上检查或列出已安装的安全更新的两种方法
  7. 周立功上位机获取CAN通讯数据解析 V2.0
  8. RANSAC算法——看完保证你理解
  9. 如何设计一款智能烧烤锅?
  10. linux win10虚拟内存,Win10虚拟内存设置多少合适?这样设置就最好!
  11. netbeans php下载,Netbeans7下载和安装
  12. DfE给学生提供的笔记本电脑感染了恶意软件
  13. 什么是Python?Python简介
  14. 【写着玩】二维码检测及定位
  15. 撩小姐姐的小程序(二)----旋转3D八音盒
  16. Linux 音频驱动(一) ASoC音频框架简介
  17. 沈阳大雨部分地区积水情况
  18. 我的世界服务器怎么弄领地语言,我的世界领地指令权限大全 我的世界领地指令设置教程...
  19. java connect four_JAVA connectFour
  20. 语义化的理解:有哪些语义化标签?有什么作用?

热门文章

  1. Parcel Bundle漏洞学习
  2. 教育部高等学校大学计算机课程教学指导委员会,2018-2022教育部高等学校工科基础课程教学指导委员会2018年全体委员会议在北京召开...
  3. 区块链应用 | 泡沫之下的区块链
  4. 汇编语言 实现1.将数据区buf1中的10个数,传送到数据区buf2 2.计算buf1数据的累加和
  5. (附源码)node.js华联招聘网站 毕业设计 011229
  6. 外刊IT网站经典计算机开发,评论,总结文章汇总共享
  7. 深度解读 | 从Gartner SIEM魔力象限报告看安全运营的门道
  8. WEBDisk网络硬盘
  9. c语言算法:排队打饭
  10. 算法模型好坏、评价标准、算法系统设计