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. Android线程间通信的几种实现方式

    1. 通过Handler机制: private void one() { handler=new Handler(){ @Override public void handleMessage(Mess ...

  2. python 从csv文件插入mysql数据库

    一个工作遇到的问题,将excel文件的内容插入到mysql数据库中. 总体思路是 excel文件-->转换成csv文件-->csv文件读取-->读取数据插入mysql数据库 用到py ...

  3. 脚本_检测mysql存活状态

    #!bin/bash#功能:检测mysql服务是否存活#作者:liusingbon# host为你需要检测的mysql主机的IP 地址,user为mysql账户名,passwd为密码; 这些信息需要根 ...

  4. 吉首大学2019年程序设计竞赛(重现赛) J 滑稽树下你和我 (递归)

    链接:https://ac.nowcoder.com/acm/contest/992/J来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32768K,其他语言65536K ...

  5. Vue列表渲染-变异方法

    Vue 包含一组观察数组的变异方法,变异方法 (mutation method),顾名思义,会改变被这些方法调用的原始数组 所以它们也将会触发视图更新.这些方法如下: push() pop() shi ...

  6. TCP协议之三次握手四次挥手

    一.TCP协议简述 TCP协议位于传输层用来建立传输数据的通道以及传输数据,那么在这一层的tcp协议就涉及到客户端与服务端通信的连接,数据的传输.关闭连接. 通信的连接使用的就是客户端与服务端的三次握 ...

  7. 前端-PC端瀑布流【10张图】

    .HTML 利用封装的 jquerywaterfall.js 方法 完成 <!DOCTYPE html> <html lang="en"> <head ...

  8. Excel,此文件中的某些文本格式可能已经更改,因为它已经超出最多允许的字体数。

    既然是超出最多允许的字体数,那么就不要循环创建IFont.先创建一个IFont font=wk.CreateFont();后面都使用它即可.

  9. httpClient连接工具类实测可用

    package com.jeecms.common.util; import com.google.gson.Gson; import com.jeecms.cms.api.Constants; im ...

  10. 学习笔记:Apache Kylin 概述

    一.kylin解决了什么关键问题? Apache Kylin的初衷就是解决千亿.万亿条记录的秒级查询问题,其中的关键就是打破查询时间随着数据量呈线性增长的这一规律. 大数据OLAP,我们可以注意到两个 ...