πŸš€ Phases 1–5 are live β€” Days 1–17 cover the foundations and the algorithmic patterns. See the roadmap β†’

Partition Equal Subset Sum medium

Description

Given a non-empty array nums containing only positive integers, decide whether it can be partitioned into two subsets such that the sum of elements in both subsets is equal.

Examples

> Case 1:
    nums = [1, 5, 11, 5]
    Output: true
    Explanation: [1, 5, 5] and [11] both sum to 11.
 
> Case 2:
    nums = [1, 2, 3, 5]
    Output: false
    Explanation: total is 11, which is odd. Can't split evenly.

Constraints

  • 1 <= nums.length <= 200
  • 1 <= nums[i] <= 100

The reduction

A two-way split with equal sums means each side equals total / 2. So the question becomes: does some subset of nums sum to exactly total / 2?

That’s subset-sum, which is 0/1 knapsack in disguise:

  • Item weights = the numbers themselves.
  • Item values = irrelevant (we only need existence).
  • Capacity = total / 2.
  • Question = β€œcan we exactly fill the knapsack?”

If total is odd, immediately return false. Otherwise, build a boolean DP.

State design

  1. What am I computing? dp[w] = true if some subset of nums sums to exactly w.
  2. Dimensions? One β€” target sum w. (We collapse the item index away with the reverse-loop trick.)
  3. Base cases? dp[0] = true (the empty subset sums to 0). All other entries false.
  4. Transition? For each number x in nums, for each w from target down to x: dp[w] = dp[w] OR dp[w - x].
  5. Order? Iterate x in any order; inner loop w must be reverse (0/1 knapsack rule).
  6. Answer? dp[total / 2].

Code

A micro-optimization with bitsets

In C++, you can use std::bitset to do the entire row update in a single shift-and-OR β€” making the inner loop effectively O(target / 64):

bool canPartition(vector<int>& nums) {
    int total = accumulate(nums.begin(), nums.end(), 0);
    if (total % 2 != 0) return false;
    bitset<10001> dp;
    dp[0] = 1;
    for (int x : nums) dp |= (dp << x);
    return dp[total / 2];
}

Same algorithm, 64x speedup. Knowing this trick is the difference between a competitive-programming submission and an interview answer.

Analysis

  • Time: O(n Γ— total / 2) = O(n Γ— sum / 2).
  • Space: O(sum / 2).

Same skin

  • Target Sum β€” assign +/βˆ’ signs to each number to hit target; the positive subset must sum to (total + target) / 2. Same subset-sum DP.
  • Last Stone Weight II β€” minimize |sum_A βˆ’ sum_B|; equivalently, find the subset closest to total / 2.
  • Ones and Zeroes β€” two-dimensional capacity (count of 0s and 1s), same DP shape.