class Solution:
def canPartition(self, nums):
total = sum(nums)
# If total sum is odd, cannot partition equally
if total % 2 != 0:
return False
target = total // 2
dp = set([0])
for num in nums:
next_dp = set(dp)
for t in dp:
if t + num == target:
return True
if t + num <= target:
next_dp.add(t + num)
dp = next_dp
return target in dp
class Solution {
public:
bool canPartition(vector<int>& nums) {
int total = accumulate(nums.begin(), nums.end(), 0);
if (total % 2 != 0) return false;
int target = total / 2;
unordered_set<int> dp = {0};
for (int num : nums) {
unordered_set<int> next_dp(dp);
for (int t : dp) {
if (t + num == target) return true;
if (t + num <= target) next_dp.insert(t + num);
}
dp = next_dp;
}
return dp.count(target) > 0;
}
};
class Solution {
public boolean canPartition(int[] nums) {
int total = 0;
for (int n : nums) total += n;
if (total % 2 != 0) return false;
int target = total / 2;
HashSet<Integer> dp = new HashSet<>();
dp.add(0);
for (int num : nums) {
HashSet<Integer> nextDp = new HashSet<>(dp);
for (int t : dp) {
if (t + num == target) return true;
if (t + num <= target) nextDp.add(t + num);
}
dp = nextDp;
}
return dp.contains(target);
}
}
var canPartition = function(nums) {
let total = nums.reduce((a, b) => a + b, 0);
if (total % 2 !== 0) return false;
let target = total / 2;
let dp = new Set([0]);
for (let num of nums) {
let nextDp = new Set(dp);
for (let t of dp) {
if (t + num === target) return true;
if (t + num <= target) nextDp.add(t + num);
}
dp = nextDp;
}
return dp.has(target);
};
Given a non-empty array nums
containing only positive integers, determine if it can be partitioned into two subsets such that the sum of elements in both subsets is equal.
nums
in both subsets.true
if such a partition exists, otherwise false
.Constraints:
nums.length
<= 200nums[i]
<= 100The heart of the problem is deciding whether the array can be split into two groups with equal sums. At first glance, this seems related to finding all possible subsets and checking their sums, but that would be very inefficient for larger arrays.
If the total sum of the array is odd, it's immediately impossible—two equal integers can't sum to an odd number. If it's even, we need to determine whether any subset sums exactly to half the total (the other subset will automatically sum to the other half).
This leads to the classic "Subset Sum" problem: can we pick a subset of numbers from nums
that adds up to a target (here, half the total)? Brute-forcing all subset combinations is exponential, so we look for optimizations, such as dynamic programming, to efficiently track which sums are possible as we process each number.
We use a dynamic programming approach to solve the subset sum problem efficiently.
false
immediately.
target = total_sum / 2
. Our goal is to find a subset that sums to target
.
0
as the only achievable sum.
nums
:
sum + num
(if it's not above target
).target
, return true
early.target
is in the set of achievable sums, return true
; otherwise, return false
.
We use a set for possible sums because lookups and insertions are fast (O(1) average), and it avoids duplicates as we expand the set with each new number.
Consider nums = [1, 5, 11, 5]
.
true
.The process stops as soon as we reach the target sum, confirming that a valid partition exists.
The optimized approach is much more efficient and feasible for the given constraints.
The Partition Equal Subset Sum problem boils down to determining if a subset of the array sums to exactly half the total. By using dynamic programming to efficiently track achievable sums as we process each number, we avoid the exponential blowup of brute-force solutions. The key insight is that if the total sum is odd, partitioning is impossible; otherwise, we check for the existence of a subset with sum equal to half the total. This approach is both elegant and practical for moderate input sizes.