THN Interview Prep

416. Partition Equal Subset Sum

At a Glance

  • Topic: dp-1d
  • Pattern: Dynamic Programming (0/1 knapsack reachability)
  • Difficulty: Medium
  • Companies: Facebook, Amazon, Google, Bloomberg, Microsoft
  • Frequency: High
  • LeetCode: 416

Problem (one-liner)

Given positive integers nums, determine whether they can be partitioned into two subsets with equal sum. Input: nums. Output: true/false.

Recognition Cues

  • “Partition into two equal-sum subsets”
  • Total must be even; target half-sum is sum/2
  • Each number used at most once → 0/1 knapsack “can we hit target?”

Diagram

At-a-glance flow (replace with problem-specific Mermaid as you refine this note). camelCase node IDs; no spaces in IDs.

Loading diagram…

Approaches

  • Brute force2^n subset sums.
  • Better — bitset / set of reachable sums — O(n * target) time.
  • Optimal — boolean 1D DP rolling over sums — O(n * target) time / O(target) space. <- pick this in interview.

Optimal Solution

Go

package main

func canPartitionFullTable(nums []int) bool {
	total := 0
	for _, value := range nums {
		total += value
	}
	if total%2 == 1 {
		return false
	}
	target := total / 2
	length := len(nums)
	table := make([][]bool, length+1)
	for index := range table {
		table[index] = make([]bool, target+1)
	}
	for index := 0; index <= length; index++ {
		table[index][0] = true
	}
	for itemIndex := 1; itemIndex <= length; itemIndex++ {
		value := nums[itemIndex-1]
		for sum := 1; sum <= target; sum++ {
			if sum < value {
				table[itemIndex][sum] = table[itemIndex-1][sum]
			} else {
				table[itemIndex][sum] = table[itemIndex-1][sum] || table[itemIndex-1][sum-value]
			}
		}
	}
	return table[length][target]
}

func canPartition(nums []int) bool {
	total := 0
	for _, value := range nums {
		total += value
	}
	if total%2 == 1 {
		return false
	}
	target := total / 2
	reachable := make([]bool, target+1)
	reachable[0] = true
	for _, value := range nums {
		for sum := target; sum >= value; sum-- {
			if reachable[sum-value] {
				reachable[sum] = true
			}
		}
	}
	return reachable[target]
}

JavaScript

function canPartitionFullTable(nums) {
	let total = 0;
	for (const value of nums) {
		total += value;
	}
	if (total % 2 === 1) return false;
	const target = total / 2;
	const length = nums.length;
	const table = Array.from({ length: length + 1 }, () =>
		new Array(target + 1).fill(false)
	);
	for (let index = 0; index <= length; index++) {
		table[index][0] = true;
	}
	for (let itemIndex = 1; itemIndex <= length; itemIndex++) {
		const value = nums[itemIndex - 1];
		for (let sum = 1; sum <= target; sum++) {
			if (sum < value) {
				table[itemIndex][sum] = table[itemIndex - 1][sum];
			} else {
				table[itemIndex][sum] =
					table[itemIndex - 1][sum] ||
					table[itemIndex - 1][sum - value];
			}
		}
	}
	return table[length][target];
}

function canPartition(nums) {
	let total = 0;
	for (const value of nums) {
		total += value;
	}
	if (total % 2 === 1) return false;
	const target = total / 2;
	const reachable = new Array(target + 1).fill(false);
	reachable[0] = true;
	for (const value of nums) {
		for (let sum = target; sum >= value; sum--) {
			if (reachable[sum - value]) {
				reachable[sum] = true;
			}
		}
	}
	return reachable[target];
}

Walkthrough

Input: nums = [1,5,11,5]

  • Total 22, target 11.
  • After processing 1: reachable {0,1}.
  • After 5: {0,1,5,6}.
  • After 11: includes 11 from 0+11.
  • Return true.

Invariant: after each number, reachable[sum] iff some subset of processed numbers sums to sum. Iterate sums descending to avoid reusing the same element twice in one pass.

Edge Cases

  • Total odd → false immediately
  • Single element → false for partition into two non-empty (problem usually implies two disjoint subsets; length 1 fails)
  • Large target still bounded by sum of nums

Pitfalls

  • Forward iteration on inner loop (turns 0/1 into unbounded)
  • Forgetting reachable[0]=true
  • Integer overflow when summing (use 64-bit if needed)

Similar Problems

Variants

  • Partition into k equal-sum subsets → backtracking + memo (different complexity).
  • Count partitions → use integer DP instead of boolean.

Mind-Map Tags

#01-knapsack #subset-sum #partition #boolean-dp #medium

Last updated on

Spotted something unclear or wrong on this page?

On this page