Partition Equal Subset Sum

本文探讨了一个经典的计算机科学问题——如何判断一个正整数数组能否被分割成两个子集,使得这两个子集的元素之和相等。通过动态规划的方法,我们将此问题转化为背包问题进行求解,并提供了一个高效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

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.

题目大意:

这道题目意思是给定一个正整数的数组,问我们这个数组能不能分成两个非空子集合,使得两个子集合的元素之和相同。

解题思路:

采用动态规划的思想,将这个问题抽象成一个背包问题,也就是说给定n个数,第i个数价值为nums[i]。定义一个大小为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(int j=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;
    }
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值