Partition Equal Subset Sum
Master this topic with zero to advance depth.
Partition Equal Subset Sum
Given an integer array nums, return true if you can partition the array into two subsets such that the sum of the elements in both subsets is equal or false otherwise.
Visual Representation
nums = [1, 5, 11, 5]
Total Sum = 22, Target = 11
Subsets:
[1, 5, 5] -> Sum 11
[11] -> Sum 11
Result: True
Logic:
Can we find a subset with sum equal to (TotalSum / 2)?Examples
The array can be partitioned as [1, 5, 5] and [11].
Level I: Dynamic Programming (Bottom-Up 2D)
Intuition
This is a variation of the 0/1 Knapsack Problem. We want to find if there's a subset with sum = totalSum / 2.
Thought Process
- If
totalSumis odd, returnfalse(cannot partition equally). - Target =
totalSum / 2. dp[i][j]= true if sumjcan be formed using firstielements.dp[i][j] = dp[i-1][j](exclude current) ORdp[i-1][j - nums[i]](include current, ifj >= nums[i]).
Detailed Dry Run
nums = [1, 5, 5], Target = 5.5 (Skip, 11 is total) nums = [1, 2, 3], Target = 3
| i | x | Sum 0 | Sum 1 | Sum 2 | Sum 3 | Action |
|---|---|---|---|---|---|---|
| 0 | 1 | T | T | F | F | Init |
| 1 | 2 | T | T | T | T | dp[0][3] |
| Result | T | True! |
Level II: Memoization (Top-Down)
Intuition
The 2D DP bottom-up approach explores the entire grid. A top-down memoized approach explores only the reachable states. Both have the same complexity but memoization is more intuitive to derive.
Visual
nums=[1,5,11,5], target=11
solve(4, 11): can_pick(11)? No, but 11<11 is false for nums[3]=5
solve(3, 6): can_pick(11)? ...Detailed Dry Run
nums=[1,5,5,11], target=11. solve(3, 11) = take 11 = solve(2, 0) = True! Cached.
⚠️ Common Pitfalls & Tips
String keys for memoization in C++/Go/Java are slow. A 2D boolean array with i and t as indices is faster and preferred in practice.
Level III: Space Optimized (1D)
Intuition
Since dp[i][j] only depends on the previous row dp[i-1], we can use a single row array. To avoid using the same element twice for the same sum (0/1 constraint), we iterate the sum backwards.
Logic Steps
- Initialize a
dparray of sizetarget + 1withfalse. dp[0] = true.- For each
numinnums:- For
jfromtargetdown tonum:dp[j] = dp[j] || dp[j - num].
- For
Detailed Dry Run
nums = [1, 2, 3], Target = 3
| num | Target 3 | Target 2 | Target 1 | Target 0 |
|---|---|---|---|---|
| - | F | F | F | T |
| 1 | F | F | T (0+1) | T |
| 2 | T (1+2) | T (0+2) | T | T |
| 3 | T (0+3) | T | T | T |
⚠️ Common Pitfalls & Tips
You must iterate the inner loop backwards (from target to num). If you iterate forwards, you might use the same element multiple times for the same sum (which is unbounded knapsack behavior, not 0/1).
Found an issue or have a suggestion?
Help us improve! Report bugs or suggest new features on our Telegram group.