问题描述:

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

动态规划求解

  这是一个0-1背包问题的变种,也就是每种物品只能选择一次。与之对应的是完全背包问题,选择每种物品的数量是不限制的,可以与另一篇博文对照来看。将非空数组 nums,分为两部分,使得两部分的和相等,该问题等价于从数组中选择部分数字,使得其和等于数组总和的一半。特别的当数组总和sum为基奇数,不可能将数组拆成相等的两部分,直接返回false。
  令dp[i][j]dp[ i ][ j ]dp[i][j]表示,选择数组前iii个元素,其和是否能为jjj。则有:
  当j>=nums[i−1]j >= nums[i-1]j>=nums[i−1]时, 可以选择不添加该元素直接得到j,或者由添加该元素得到j,即
dp[i][j]=dp[i−1][j]∣∣dp[i−1][j−nums[i−1]]dp[ i ][ j ] = dp[i-1][j] || dp[i-1][j-nums[i-1]]dp[i][j]=dp[i−1][j]∣∣dp[i−1][j−nums[i−1]]
   当j<nums[i−1]j < nums[i-1]j<nums[i−1]时,当前元素不可选择,否则会直接超出j,有
dp[i][j]=dp[i−1][j]dp[ i ][ j ] = dp[i-1][j]dp[i][j]=dp[i−1][j]
   特别的dp[0][0]=1dp[ 0 ][ 0 ] = 1dp[0][0]=1,因为和为0只有一种情况:不选择任何元素。
   在本示例中有,dp[2][6]=dp[1][6−nums[1]]∣∣dp[1][6]=dp[1][1]∣∣dp[1][6]=truedp[2][6] = dp[1][6-nums[1]] || dp[1][6] = dp[1][1] || dp[1][6] = truedp[2][6]=dp[1][6−nums[1]]∣∣dp[1][6]=dp[1][1]∣∣dp[1][6]=true,返回值即为dp[nums.length][sum/2]=dp[4][11]=truedp[nums.length][sum/2] = dp[4][11] = truedp[nums.length][sum/2]=dp[4][11]=true。

  程序实现需要编写两层循环,分别对应数组长度iii和和jjj。需要注意的是iii循环时从1开始,总数jjj循环时从0开始,第iii元素的值为nums[i−1]nums[i-1]nums[i−1]。运行结果为33 ms 42.4 MB。

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

空间复杂度优化

考虑到dp[i][j]dp[ i ][ j ]dp[i][j]的值仅与第i−1i-1i−1行有关系,可以采用滚动数组的思想来降低空闲复杂度。具体的,只维护一维的dpdpdp数组,其状态更新关系为:
dp[j]=dp[j−nums[i−1]]+dp[j]dp[ j ] = dp[ j-nums[i-1]] + dp[j] dp[j]=dp[j−nums[i−1]]+dp[j]

  需要注意的是,第二层的循环我们需要从大到小计算,因为如果我们从小到大更新 dpdpdp值,那么在计算 dp[j]dp[j]dp[j] 值的时候, dp[j−nums[i−1]]dp[j- nums[i-1]]dp[j−nums[i−1]]已经是被更新过的状态,不再是上一行的 dpdpdp 值。运行结果为 19 ms 39.6 MB,可以看到空间使用情况有所降低。

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

[动态规划] leetcode 416. 分割等和子集相关推荐

  1. LeetCode 416 分割等和子集

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

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

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

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

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

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

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

  5. leetcode 416. 分割等和子集

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

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

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

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

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

  8. 动态规划:leetcode 416 分割等和子集(背包问题应用)

    题目链接:力扣 定义dp数组:dp[i][j]表示能否从nums下标0~j任意选择数,使它们之和为j,dp数组为bool类型 状态转移方程:下标为i的数不选,dp[i][j]等价于dp[i-1][j] ...

  9. LeetCode #416 分割等和子集

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

最新文章

  1. 灰度图像的对数变换原理及OpenCV代码实现
  2. 前端ajax封装对象数组,后台的取法
  3. 【运筹学】线性规划数学模型 ( 单纯形法 | 最优解判定原则 | 单纯形表 | 系数计算方法 | 根据系数是否小于等于 0 判定最优解 )
  4. 谭浩强C语言程序设计 学习辅导练习题
  5. 非常便捷的本地Mock
  6. HashMap 详解
  7. access工资明细表_《ACCESS》工资管理完整(整理).doc
  8. java捕捉音频,如何捕获在Java中的音频数据
  9. pat 乙级 1019 数字黑洞(C++)
  10. JasperReport报表导出PDF中文不显示的问题
  11. matlab 自带定积分,Matlab怎么计算定积分,划重点了
  12. Python答题并统计的小程序
  13. reviewboard mysql_【ReviewBoard】安装与配置
  14. 帆软报表设置的参数不显示_FineReport报表工具显示格式和显示值的设置
  15. 一个可以把Google Docs变成GDrive的工具
  16. Python 自除数
  17. 会计记录accton
  18. hive SQL 过滤不含数字的字段
  19. EXCEL之工资表转工资条
  20. mysql使索引失效语句_mysql语句中索引可能失效的情况

热门文章

  1. 头脑王者类似源码研究
  2. 高效能技术领导者,不仅是首席技术官,更是首席情绪官
  3. BYK-A500消泡剂:泡沫的一切都在计算中
  4. 电子产品高温贮存试验的价格-第三方检测机构
  5. 知识产权日特稿:谁动了程序员的源代码版权?
  6. html5锥形,Three.js HTML5 3D开发实例 - 彩色圆锥体
  7. Synchronized Lock 锁 同步
  8. 不同版本cuda对应的NVIDIA驱动版本
  9. 【归并排序】【洛谷】【P1309-瑞士轮】
  10. 当前年的日历存储到数据库,用于判断某一天是假期还是工作日