您的位置:首页 > 其它

416. Partition Equal Subset Sum

2016-10-26 17:11 281 查看
原题如下:

Partition Equal Subset Sum
Given a
non-empty arraycontaining
only positive integers, find if the array can be partitionedinto 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: Thearray can be partitioned as [1, 5, 5] and [11].

Example 2:

Input: [1, 2, 3, 5]
 
Output: false
 
Explanation: Thearray cannot be partitioned into equal sum subsets.

题目大意:这道题目意思大概是给定一个正整数的数组,看是否这个正整数的数组能够两部分,每部分的和相等。

解题思路:这道题目如果用暴力的方法挺复杂的,将数组中所有不同情况的数字组合起来,这样的复杂度达到了指数的级别,显然不是一种很好的方法;这里我们采用动态规划的思想,将这个问题抽象成一个背包问题,也就是说给定n个数,第i个数价值为nums[i],现在就是判断是否存在能让背包里装价值为sum/2的情况,我们定义一个大小为sum/2(sum为数组中所有元素的和)的数组,然后根据状态转移方程f[v]=max{f[v],f[v-c[i]]+w[i]}计算出f[sum/2],然后判断f[sum/2]是否等于sum/2,是的话,返回true,否则,返回false;

算法:

1、       求出数组的和sum,而且判断sum是否为偶数,不为偶数的话显然不能对半分,这个时候返回false即可,

2、       若sum的值为偶数,则定义一个大小为sum/2+1的数组f,并初始化为0;

3、       然后用一个二重循环,外层循环是i-n(n为数组大小),内层循环则是从sum/2到0,这里顺序不能颠倒,这样使用内层循环可以节省空间,然后根据状态转移方程f[v]=max{f[v],f[v-c[i]]+w[i]}计算出结果。

4、       循环结束后,判断f[sum/2]是否等于sum/2,是的话返回true,否则返回false。

算法复杂度分析:整个函数只用了两层循环解决问题,所以最坏复杂度为O(NV),其中N是数组大小,V是数组总和的一半。

具体代码如下:

class Solution {

public:

    bool canPartition(vector<int>&nums) {

        int n=nums.size();

        if(n==0)return true;

        if(n==1)return false;

        int sum=0;

        for(int i=0;i<n;i++){

             sum+=nums[i];

        }

        if(sum%2==1)

        return false;

        vector<int> t(sum/2+1,0);

        //vector<vector<int> >t(n+1,temp);

        for(int i=1;i<=n;i++){

             for(intj=sum/2;j>=0;j--){

                 if(j>=nums[i-1])

                    t[j]=max(t[j],t[j-nums[i-1]]+nums[i-1]);

             }

        }

        return t[sum/2]==sum/2;

    }

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: