58.Partition Equal Subset Sum(判断一个数组是否可以分成和相等的两个数组)
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:
- Each of the array element will not exceed 100.
 - 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(判断一个数组是否可以分成和相等的两个数组)的更多相关文章
- LN : leetcode 416 Partition Equal Subset Sum
		
lc 416 Partition Equal Subset Sum 416 Partition Equal Subset Sum Given a non-empty array containing ...
 - 416. Partition Equal Subset Sum
		
题目: Given a non-empty array containing only positive integers, find if the array can be partitioned ...
 - [LeetCode] Partition Equal Subset Sum 相同子集和分割
		
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
 - [LeetCode] 416. Partition Equal Subset Sum 相同子集和分割
		
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
 - Partition Equal Subset Sum
		
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
 - [刷题] 416 Partition Equal Subset Sum
		
要求 非空数组的所有数字都是正整数,是否可以将这个数组的元素分成两部分,使得每部分的数字和相等 最多200个数字,每个数字最大为100 示例 [1,5,11,5],返回 true [1,2,3,5], ...
 - [leetcode]416. Partition Equal Subset Sum分割数组的和相同子集
		
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
 - 【LeetCode】416. Partition Equal Subset Sum 解题报告(Python & C++)
		
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 DFS 动态规划 日期 题目地址:https://l ...
 - Leetcode 416. Partition Equal Subset Sum
		
Given a non-empty array containing only positive integers, find if the array can be partitioned into ...
 
随机推荐
- JS中的reduce函数
			
海纳百川,有容乃大 定义: reduce()方法接受一个函数作为累加器,数组中的每个值(从左向右)开始缩减,最终计算为一个值.对空数组是不会执行回调函数的. 案例: 计算数组总和: var num = ...
 - day02 循环、格式化输出、运算符、编码
			
01 昨日内容回顾 python2x python3x区别: python2x:源码重复,不规范. python3x:源码规范,优美,清晰,简单. 编译型:将代码一次性全部转化成字节码. 代表语言:C ...
 - React(4) --引入图片及循环数据
			
引入图片的方法 1.引入本地图片 方法1: import logo from '../assets/images/1.jpg'; <img src={logo} /> 方法2: <i ...
 - springboot创建一个服务,向eureka中注册,使用swagger2进行服务管理
			
首先pom.xml文件,spring boot.springcloud版本很麻烦,容易出问题 <?xml version="1.0" encoding="UTF-8 ...
 - phpstorm 各种报错
			
1.启动时报错 Failed to load module "canberra-gtk-module" 解决方法:libcanberra-gtk-module sudo apt-g ...
 - java Map的四种遍历方式
			
1.这是最常见的并且在大多数情况下也是最可取的遍历方式,在键值都需要时使用. Map<Integer, Integer> map = new HashMap<Integer, Int ...
 - oracle多表连接方式Hash Join Nested Loop Join Merge Join
			
在查看sql执行计划时,我们会发现表的连接方式有多种,本文对表的连接方式进行介绍以便更好看懂执行计划和理解sql执行原理. 一.连接方式: 嵌套循环(Nested Loops (NL) ...
 - Struts第一个程序。
			
1:创建完程序后.先写web.xml <?xml version="1.0" encoding="UTF-8"?> <web-app xmln ...
 - 4412 linux延时和时间
			
基本知识 • linux中延时函数很简单,却经常用到• 在操作系统中和单片机处理延时方式就完全不一样了,不可能是使用for循环浪费系统资源.而是有专门的接口函数• linux系统编程中常用的延时函数: ...
 - vue项目git
			
https://github.com/renrenio/renren-fast-vue https://github.com/hzlshen/vue-project