Level:

  Medium

题目描述:

Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.

Note:

  1. Each of the array element will not exceed 100.
  2. The array size will not exceed 200.

Example 1:

Input: [1, 5, 11, 5]

Output: true

Explanation: The array can be partitioned as [1, 5, 5] and [11].

Example 2:

Input: [1, 2, 3, 5]

Output: false

Explanation: The array cannot be partitioned into equal sum subsets.

思路分析:

  方法一:利用暴力的dfs进行遍历,找数组中有么有和为sum/2的组合,先看sum是否为偶数,如果为奇数直接false。

  方法二:动态规划的思想。我们定义一个一维的dp数组,其中dp[i]表示原数组是否可以取出若干个数字,其和为i。那么我们最后只需要返回dp[target]就行了。初始化dp[0]为true,由于题目中限制了所有数字为正数,那么就不用担心会出现和为0或者负数的情况。关键问题就是要找出状态转移方程了,我们需要遍历原数组中的数字,对于遍历到的每个数字nums[i],需要更新dp数组,我们的最终目标是想知道dp[target]的boolean值,就要想办法用数组中的数字去凑出target,因为都是正数,所以只会越加越大,那么加上nums[i]就有可能会组成区间 [nums[i], target] 中的某个值,那么对于这个区间中的任意一个数字j,如果 dp[j - nums[i]] 为true的话,说明现在已经可以组成 j-nums[i] 这个数字了,再加上nums[i],就可以组成数字j了,那么dp[j]就一定为true。如果之前dp[j]已经为true了,当然还要保持true,所以还要‘或’上自身,于是状态转移方程如下:

dp[j] = dp[j] || dp[j - nums[i]] (nums[i] <= j <= target)

有了状态转移方程,那么我们就可以写出代码了,这里需要特别注意的是,第二个for循环一定要从target遍历到nums[i],而不能反过来,想想为什么呢?因为如果我们从nums[i]遍历到target的话,假如nums[i]=1的话,那么[1, target]中所有的dp值都是true,因为dp[0]是true,dp[1]会或上dp[0],为true,dp[2]会或上dp[1],为true,依此类推,完全使我们的dp数组失效了。

代码:

思路一:

public class Solution{
public boolean canPartition(int []nums){
int sum=0;
for(int i=0;i<nums.length;i++){
sum=sum+nums[i];
}
if(sum%2==1)
return false;
sum=sum/2;
Arrays.sort(nums);//排序,方剪枝
return dfs(0,sum,nums);
}
public boolean dfs(int index,int sum,int []nums){
if(index<nums.length&&nums[index]==sum)
return true;
if(index<nums.length&&nums[index]>sum)
return false;
return dfs(index+1,sum-nums[index],nums)||dfs(index+1,sum,nums);
}
}

思路二:

public class Solution{
public boolean canPartition(int []nums){
int sum=0;
for(int i=0;i<nums.length;i++){
sum=sum+nums[i];
}
if(sum%2==1)
return false;
sum=sum/2;
boolean []dp=new boolean[sum+1];//dp[i]表示和为i能否由数组中部分元素构成
Arrays.fill(dp,false);
dp[0]=true;
for(int num:nums){
for(int i=sum;i>=num;i--){
dp[i]=dp[i]||dp[i-num];
}
}
return dp[sum];
}
}

58.Partition Equal Subset Sum(判断一个数组是否可以分成和相等的两个数组)的更多相关文章

  1. LN : leetcode 416 Partition Equal Subset Sum

    lc 416 Partition Equal Subset Sum 416 Partition Equal Subset Sum Given a non-empty array containing ...

  2. 416. Partition Equal Subset Sum

    题目: Given a non-empty array containing only positive integers, find if the array can be partitioned ...

  3. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  4. [LeetCode] 416. Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  5. Partition Equal Subset Sum

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  6. [刷题] 416 Partition Equal Subset Sum

    要求 非空数组的所有数字都是正整数,是否可以将这个数组的元素分成两部分,使得每部分的数字和相等 最多200个数字,每个数字最大为100 示例 [1,5,11,5],返回 true [1,2,3,5], ...

  7. [leetcode]416. Partition Equal Subset Sum分割数组的和相同子集

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  8. 【LeetCode】416. Partition Equal Subset Sum 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 动态规划 日期 题目地址:https://l ...

  9. Leetcode 416. Partition Equal Subset Sum

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

随机推荐

  1. 解析天启rk3288源码 /kernel/drivers/char/virtd

    virtd为编译后产生的中间文件,可使用ELF格式逆向 1.ELF文件内容解析readelf: 可解析ELF文件的所有内容;strings: 查看ELF文件中的字符串;file   : 查看ELF文件 ...

  2. EBCDIC 870 Poland

    Characters are shown with their equivalent Unicode codes.

  3. 前端每日实战:63# 视频演示如何用纯 CSS 创作一台烤面包机

    效果预览 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/OEBJRN 可交互视频 此视频是可 ...

  4. Scene Text Detection(场景文本检测)论文思路总结

    任意角度的场景文本检测论文思路总结共同点:重新添加分支的创新更突出场景文本检测基于分割的检测方法 spcnet(mask_rcnn+tcm+rescore) psenet(渐进扩展) mask tex ...

  5. join()、split()

    join()用于把数组转化为字符串 var arr=['hello','world','kugou']; document.write(arr.join(''));//helloworldkugou ...

  6. 前端-使用template-web.js【模版引擎】渲染数据

    通过ajax请求到的数据,使用传统的拼接字符串也可以做到,但是‘ “ ” ‘这种模式,单引号.双引号容易 扩错,新手入门推荐使用这种,初入前端,需要一个一个敲代码体会一下. 使用 template.j ...

  7. mybatis的Date类型。

    在写select的时候,里面的查询语句.where后面如果jdbcType=DATE没有写的话是 这个形式的. <select id="selectPhoto" parame ...

  8. PHP curl_multi_getcontent函数

    curl_multi_getcontent — 如果设置了CURLOPT_RETURNTRANSFER,则返回获取的输出的文本流 说明 string curl_multi_getcontent ( r ...

  9. 08-图7 公路村村通(30 分)Prim

    现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本. 输入格式: 输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N) ...

  10. JavaScript中的编码解码

    1.URI 统一资源标识符(URI)是一个用于标识某一互联网资源名称的字符串.,该种标识允许用户对任何(包括本地和互联网)的资源通过特定的协议进行交互操作.Web上可用的每种资源 -HTML文档.图像 ...