Partition Equal Subset Sum
Solve this ProblemTest Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 20 - ◆
1 ≤ nums[i] ≤ 100
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
Approach & Solutions
Brute Force — Recursive Without Memoization
BruteSplitting the array into two equal-sum groups is only possible if the total is even in the first place — an odd total can never be split into two identical halves. When it is even, the question becomes: can some subset of the array sum to exactly half the total? Whatever that subset is, the rest of the array automatically forms the other half with the same sum. That reduces this problem to the same include/exclude search used for finding a subset that hits a target: at every number, try leaving it out and try taking it, and succeed the moment some combination reaches exactly half the total.
O(2^n)O(n)1class Solution {
2 private int[] nums;
3
4 public boolean canPartition(int[] nums) {
5 this.nums = nums;
6 int total = 0;
7 for (int num : nums) total += num;
8 if (total % 2 != 0) return false;
9 return solve(0, total / 2);
10 }
11
12 private boolean solve(int i, int remaining) {
13 if (remaining == 0) return true;
14 if (i == nums.length || remaining < 0) return false;
15 return solve(i + 1, remaining) || solve(i + 1, remaining - nums[i]);
16 }
17}Optimal — Bottom-Up 1D DP
OptimalAfter confirming the total is even, the problem is exactly Subset Sum with a target of half the total: track, for every amount from 0 up to that half, whether some combination of the numbers seen so far can reach it exactly. Amount 0 always starts reachable, and each number extends every amount that was already reachable before it. Sweeping each number's inner update from the target down to that number's own value keeps every number's contribution limited to once per amount. Once every number has been swept through, the entry at half the total says whether an equal split exists.
O(n × sum)O(sum)1class Solution {
2 public boolean canPartition(int[] nums) {
3 int total = 0;
4 for (int num : nums) total += num;
5 if (total % 2 != 0) return false;
6 int target = total / 2;
7 boolean[] dp = new boolean[target + 1];
8 dp[0] = true;
9 for (int num : nums) {
10 for (int s = target; s >= num; s--) {
11 if (dp[s - num]) dp[s] = true;
12 }
13 }
14 return dp[target];
15 }
16}