Cover image for LeetCode Hot 100 P416 Partition Equal Subset Sum

LeetCode Hot 100 P416 Partition Equal Subset Sum


Timeline

Timeline

2026-03-21

init

Dynamic Programming

Problem:

Sum the subarray, then divide the sum by 2, transform to find a subset of the array that sums to half of the total, which is a 0-1 knapsack problem

dp[i][j] indicates whether there exists a selection of some positive integers (possibly zero) from the subarray [0,i] such that the sum of selected positive integers equals j. Initially, all elements in dp are false.

Initialization:

  • If no positive integer is selected, the sum of selected positive integers is 0. Therefore, for all 0 ≤ i < n, dp[i][0] = true.
  • When i==0, there is only one positive integer nums[0] that can be selected, so dp[0][nums[0]] = true.

State transition:

  • dp[i][j] = dp[i−1][j] ∣ dp[i−1][j−nums[i]](j >= nums[i])
  • dp[i][j] = dp[i-1][j](j < nums[i])
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <vector>
using std::vector;

class Solution {
public:
bool canPartition(vector<int> &nums)
{
int i, j, n = nums.size();
int sum = 0, target;

for (i = 0; i < n; i++)
sum += nums[i];

if (sum % 2 != 0) // Odd
return false;

target = sum / 2;

for (i = 0; i < n; i++) { // There is a number exceeding half of the sum
if (nums[0] > target)
return false;
}

// 0-1 knapsack problem
// dp[i][j] indicates whether there exists a selection of some positive integers (possibly zero) from the subarray [0,i] of the array
// whether there exists a selection such that the sum of the selected positive integers equals j. Initially, all elements in dp are false.
vector<vector<bool> > dp(n, vector<bool>(target + 1, false));

// If no positive integer is selected, the sum of selected positive integers is 0. Therefore, for all 0 ≤ i < n, dp[i][0] = true.
for (i = 0; i < n; i++)
dp[i][0] = true;
// When i == 0, there is only one positive integer nums[0] that can be selected, so dp[0][nums[0]] = true.
dp[0][nums[0]] = true;

// dp[i][j] = dp[i−1][j] ∣ dp[i−1][j−nums[i]] (j >= nums[i])
// dp[i][j] = dp[i-1][j] (j < nums[i])
for (i = 1; i < n; i++) {
for (j = 1; j <= target; j++) {
if (j >= nums[i])
dp[i][j] = dp[i - 1][j] | dp[i - 1][j - nums[i]];
else
dp[i][j] = dp[i - 1][j];
}
}

return dp[n - 1][target];
}
};