Back to 1 D Dp
Partition Equal Subset Sum
Partition Equal Subset Sum
š§© Problem Statement
Given an integer array nums, return true if you can partition the array into two subsets such that the sum of the elements in both subsets is equal or false otherwise.
š¹ Example 1:
Input:
nums = [1,5,11,5]
Output:
true
Explanation: The array can be partitioned as [1, 5, 5] and [11]. The sum of each subset is 11.
š¹ Example 2:
Input:
nums = [1,2,3,5]
Output:
false
Explanation: The array cannot be partitioned into equal sum subsets.
š Approaches
1. Dynamic Programming (Subset Sum Variation)
This problem is equivalent to finding a subset of nums that sums up to totalSum / 2.
- Calculate
totalSum = sum(nums). - If
totalSumis odd, we cannot divide it into two equal integers. Returnfalse. - Set
target = totalSum / 2. - Solve the Subset Sum problem for
target.
Algorithm (Space Optimized):
- Use a boolean array
dpof sizetarget + 1. dp[0] = true.- For each
numinnums: - Update
dp[j]forjfromtargetdown tonum: dp[j] = dp[j] || dp[j - num]
ā³ Time & Space Complexity
- Time Complexity: $O(N \cdot T)$, where $N$ is array length and $T$ is the target sum ($Sum/2$).
- Space Complexity: $O(T)$ for the DP array.
š Code Implementations
C++
#include <vector>
#include <numeric>
using namespace std;
class Solution {
public:
bool canPartition(vector<int>& nums) {
int totalSum = accumulate(nums.begin(), nums.end(), 0);
// If sum is odd, cannot partition into two equal integer subsets
if (totalSum % 2 != 0) return false;
int target = totalSum / 2;
vector<bool> dp(target + 1, false);
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; --j) {
if (dp[j - num]) {
dp[j] = true;
}
}
}
return dp[target];
}
};
Python
from typing import List
class Solution:
def canPartition(self, nums: List[int]) -> bool:
total_sum = sum(nums)
if total_sum % 2 != 0:
return False
target = total_sum // 2
dp = [False] * (target + 1)
dp[0] = True
for num in nums:
for j in range(target, num - 1, -1):
if dp[j - num]:
dp[j] = True
return dp[target]
Java
class Solution {
public boolean canPartition(int[] nums) {
int totalSum = 0;
for (int num : nums) totalSum += num;
if (totalSum % 2 != 0) return false;
int target = totalSum / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; j--) {
if (dp[j - num]) {
dp[j] = true;
}
}
}
return dp[target];
}
}
š Real-World Analogy
Sharing Candy:
Two siblings want to split a bag of candies so that each gets exactly the same total weight/value of candy. You sum them up, divide by 2, and seeing if you can pick pieces that sum to that exact half.
šÆ Summary
ā
Problem Reduction: This reduces directly to 0/1 Knapsack (Subset Sum) with target = sum / 2.
Solution Code
O(n) TimeO(1) Space
#include <iostream>
#include <numeric>
#include <vector>
using namespace std;
class Solution {
public:
bool canPartition(vector<int> &nums) {
int totalSum = accumulate(nums.begin(), nums.end(), 0);
// If sum is odd, cannot partition into two equal integer subsets
if (totalSum % 2 != 0)
return false;
int target = totalSum / 2;
vector<bool> dp(target + 1, false);
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; --j) {
if (dp[j - num]) {
dp[j] = true;
}
}
}
return dp[target];
}
};
int main() {
Solution sol;
vector<int> nums1 = {1, 5, 11, 5};
cout << "Test Case 1: " << (sol.canPartition(nums1) ? "True" : "False")
<< endl; // Expect True (11 = 1+5+5)
vector<int> nums2 = {1, 2, 3, 5};
cout << "Test Case 2: " << (sol.canPartition(nums2) ? "True" : "False")
<< endl; // Expect False (Sum 11, odd)
return 0;
}
SYSTEM STABLEUTF-8 ⢠STATIC_RENDER