Subset Partition
These problems are variations of the 0/1 Knapsack problem. Instead of maximizing value, we are often asking a boolean question: “Is it possible to reach a specific sum?”
1. Subset Sum Problem
Problem Statement: Given a set of non-negative integers nums and a target value target, determine if there is a subset of nums that sums up to target.
Recurrence Relation
Let dp[i][s] be a boolean value indicating if sum s is possible using the first i numbers.
- Exclude
nums[i]: Ifdp[i-1][s]is true, thendp[i][s]is true (we just ignore the new number). - Include
nums[i]: Ifs ≥ nums[i]anddp[i-1][s - nums[i]]is true, thendp[i][s]is true (we add the new number to a valid previous sum).
dp[i][s] = dp[i-1][s] || dp[i-1][s - nums[i]]
Interactive Visualization
Let’s check if we can form the Target Sum: 7 using the numbers [2, 3, 4].
[!TIP] Try it yourself: Click “Check Possibility” to fill the table. Green cells mean “Yes, possible”. The arrows show how a
Truevalue propagates.
Code Implementation: Subset Sum
// Java
public class SubsetSum {
public boolean canPartition(int[] nums, int target) {
int n = nums.length;
boolean[][] dp = new boolean[n + 1][target + 1];
// Base case: sum 0 is always possible (empty set)
for (int i = 0; i <= n; i++) {
dp[i][0] = true;
}
for (int i = 1; i <= n; i++) {
for (int s = 1; s <= target; s++) {
if (s >= nums[i - 1]) {
dp[i][s] = dp[i - 1][s] || dp[i - 1][s - nums[i - 1]];
} else {
dp[i][s] = dp[i - 1][s];
}
}
}
return dp[n][target];
}
}
// Go
func CanPartition(nums []int, target int) bool {
n := len(nums)
dp := make([][]bool, n+1)
for i := range dp {
dp[i] = make([]bool, target+1)
dp[i][0] = true // Base case
}
for i := 1; i <= n; i++ {
for s := 1; s <= target; s++ {
if s >= nums[i-1] {
dp[i][s] = dp[i-1][s] || dp[i-1][s-nums[i-1]]
} else {
dp[i][s] = dp[i-1][s]
}
}
}
return dp[n][target]
}
2. Partition Equal Subset Sum
Problem Statement: Given a non-empty array nums containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.
Insight: This is exactly the Subset Sum problem! If the total sum of the array is S, we need to find a subset with sum S/2. If S is odd, it’s impossible.
Code Implementation
// Java
public class PartitionEqualSubsetSum {
public boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
// 1D Space Optimization (iterating backwards)
for (int num : nums) {
for (int i = target; i >= num; i--) {
dp[i] = dp[i] || dp[i - num];
}
}
return dp[target];
}
}
// Go
func CanPartitionEqualSubset(nums []int) bool {
sum := 0
for _, num := range nums {
sum += num
}
if sum % 2 != 0 {
return false
}
target := sum / 2
dp := make([]bool, target+1)
dp[0] = true
// 1D Space Optimization
for _, num := range nums {
for i := target; i >= num; i-- {
if dp[i-num] {
dp[i] = true
}
}
}
return dp[target]
}
3. Deep Dive Strategy Lab: Subset Partition
Intuition Through Analogy
Think of this chapter like budget planning across months. The goal is not to memorize a fixed trick, but to repeatedly answer:
- What is the bottleneck?
- Which constraint dominates (time, memory, latency, correctness)?
- Which representation makes the bottleneck easier to eliminate?