Partition Equal Subset Sum
Partition Equal Subset Sum:
Given a non-empty array nums 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.
Example 1:
Input: nums = [1,5,11,5]
Output: true
Explanation: The array can be partitioned as [1, 5, 5] and [11].
Example 2:
Input: nums = [1,2,3,5]
Output: false
Explanation: The array cannot be partitioned into equal sum subsets.
Constraints:
1 <= nums.length <= 2001 <= nums[i] <= 100
Try this Problem on your own or check similar problems:
- Partition to K Equal Sum Subsets
- Minimize the Difference Between Target and Chosen Elements
- Maximum Number of Ways to Partition an Array
Solution:
- Java
- JavaScript
- Python
- C++
public boolean canPartition(int[] nums) {
int sum = 0;
for (int i = 0; i < nums.length; ++i) {
sum += nums[i];
}
if(sum % 2 == 1) return false;
int halfSum = sum / 2;
Set<Integer> set = new HashSet<>();
set.add(0);
for(int n : nums){
for(int j = halfSum; j >= n; --j){
if(set.contains(j-n)){
set.add(j);
}
}
}
return set.contains(halfSum);
}
/**
* @param {number[]} nums
* @return {boolean}
*/
var canPartition = function (nums) {
let sum = nums.reduce((acc, num) => acc + num, 0);
if (sum % 2 === 1) return false;
let halfSum = sum / 2;
let set = new Set();
set.add(0);
for (let num of nums) {
let tempSet = new Set(set);
for (let item of tempSet) {
if (item + num <= halfSum) {
set.add(item + num);
}
}
}
return set.has(halfSum);
};
class Solution:
def canPartition(self, nums: List[int]) -> bool:
total_sum = sum(nums)
if total_sum % 2 == 1:
return False
half_sum = total_sum // 2
set_ = {0}
for num in nums:
temp_set = set(set_)
for item in temp_set:
if item + num <= half_sum:
set_.add(item + num)
return half_sum in set_
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 == 1) {
return false;
}
int halfSum = sum / 2;
std::unordered_set<int> set;
set.insert(0);
for (int num : nums) {
std::unordered_set<int> tempSet(set);
for (int item : tempSet) {
if (item + num <= halfSum) {
set.insert(item + num);
}
}
}
return set.count(halfSum) != 0;
}
};
Time/Space Complexity:
- Time Complexity: O(n*S) where
S == halfSum - Space Complexity: O(S)
Explanation:
It's really similar to the Target Sum, we first check if sum of elements in the input array is divisible by 2, if not we immediately return false. If the sum is even, we check if we can add up to sum/2 using elements of the array. Note that this time we don't need the dp to track in how many ways we can reach the target, we only need a set that will tell us if we already can form j-n target, which basically means that if we add the current element, we could get j. At the end we check if we can get half of the target sum set.contains(halfSum). Note that we iterate first over the elements and then the target (in reverse order) which stops us from using the same element twice.