这次写的Partition Equal Subset Sum是有点类似背包问题的一道题
416 | Partition Equal Subset Sum | 38.6% | 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.要求是给定一个数组,求问能不能分成两个子数组使得这两个数组的和相等,其实就是求能不能在一个数组中找出若干个数使得和为该数组的和的一半,这里设为result,典型的背包问题。有一个不能忽略的问题就是如果result是奇数那么肯定是不可能存在的,所以要直接返回false。
还是用动态规划来解题才能够大大降低复杂度,使用穷举法当然也能够解不过时间复杂度会很高而已。
这里用了一个bool类型的vector dp来存储有可能组成我们需要的result的值,对于j来说,如果nums[i]中的数有可能组成j,dp[j]就用true来存,那么我们要求的就是dp[result]的值,同样对于数j(0<j<result)来说,如果dp[j]为true,那么加上nums[I]自然可以组成新的j,即dp[j+nums[i]]也必定为true,因此我们最终可能得到dp[result]为true,则dp[result-nums[i]]必定为true,所以我们要解题就逆过来,将题目转化为求对于nums[I]来说,是否有dp[result-nums[I]]为true。
下面上代码:
bool canPartition(vector<int>& nums)
{
int sum=0;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i];
}
if(sum%2==1)
{
return false;
}
else
{
int size=nums.size();
int result=sum/2;
vector<bool> dp;
for(int i=0;i<result+1;i++)
{
dp.push_back(false);
}
dp[0]=true;
for(int i=0;i<nums.size();i++)
{
for(int j=result;j>=nums[i];j--)
{
if(dp[j-nums[i]]==true)
{
dp[j]=true;
}
}
}
return dp[result];
}
}