Partition Equal Subset Sum⚓︎
Description⚓︎
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].
Example 2:
- Input:
nums = [1,2,3,5] - Output:
false - Explanation: The array cannot be partitioned into equal sum subsets.
Constraints:
1 <= nums.length <= 2001 <= nums[i] <= 100
Solution⚓︎
Way 1⚓︎
Connection to 0-1 Knapsack Problem:
The 0-1 Knapsack problem involves choosing items with given weights to maximize the total value without exceeding a given weight limit. Here, we tweak this idea:
- 'Weights' of items: The elements in
nums. - 'Weight limit' (knapsack capacity): Half of the total sum of elements in
nums. This is because if one subset can reach half the total sum, the other subset automatically has the remaining elements, making their sums equal. - 'Values' of items: In the traditional knapsack problem, each item has a value. Here, the value is the same as the weight, as we're interested in the sum.
The problem becomes finding a subset of nums whose sum is exactly half of the total sum.
Analysis:
- Calculate Total Sum and Target:
- First, calculate the total sum of elements in
nums. - If the sum is odd, it's impossible to split into two equal parts, hence return
false. - Otherwise, set
targetas half of the total sum. - Dynamic Programming Array Initialization:
- A
dparray of size 10001 is initialized with zeros. This array will store the best sum achievable using subsets of the elements up to the current element. - Populating the DP Array:
- For each element
numinnums, iterate backward fromtargettonum. - Update
dp[j]with the maximum ofdp[j]anddp[j - nums[i]] + nums[i].dp[j]: Best sum achievable without the current element.dp[j - nums[i]] + nums[i]: Best sum achievable by including the current element.
- This process essentially tries to find the best sum close to
targetachievable with the current set of elements. - 1-Dimensional Array for Space Optimization:
- Instead of a 2D array (common in knapsack problems), a 1D array is used.
- Each element
dp[j]gets updated based on its previous state and the statej - nums[i]steps before. - This is possible because we only need information from the previous iteration (i.e., when considering the previous element in
nums), not the entire history. - Checking for Solution:
- If
dp[target]equalstarget, it means there exists a subset ofnumswhose sum is exactlytarget. Hence, returntrue. - Otherwise, return
false.
Complexity:
- Space Complexity: Reduced from \(O(n\times \mathrm{sum})\) in a 2D approach to \(O(\mathrm{sum})\), where
sumis the total sum of elements innums. - Time Complexity: \(O(n\times \mathrm{target})\).
Way 2⚓︎
Explanation:
- Calculate Total Sum and Target:
- The total sum of elements in
numsis calculated. - If the sum is odd (
sum % 2), it's impossible to split into two equal sums, hence returnfalse. - Otherwise, the target is set to half of the total sum.
- Dynamic Programming (DP) Array Initialization:
- A
dparray of sizesum + 1is initialized to zero, exceptdp[0]which is set to 1. dp[i]will represent whether it's possible to achieve a sum ofiusing the elements fromnums.- Populating the DP Array:
- Iterate over each element
xinnums. - For each
x, iterate backward fromsumtox. - Update
dp[j]using the bitwise OR operator:dp[j] |= dp[j - x].
Understanding dp[j] |= dp[j - x]:
dp[j]: Represents if it's possible to achieve a sum ofjwith the current set of elements.dp[j - x]: Represents if it's possible to achieve a sum ofj - xwith the elements considered so far. If this is true, then addingxto this subset would achieve the sumj.
The bitwise OR operation |= is used here for a critical reason:
dp[j] |= dp[j - x]effectively setsdp[j]to 1 if eitherdp[j]was already 1 (meaning a sum ofjwas already achievable) or ifdp[j - x]is 1 (meaning by adding the current elementx, we can achieve a sum ofj).- It's a concise way of saying
dp[j] = dp[j] || dp[j - x], where||is the logical OR operator.
This approach updates the DP array to reflect whether each target sum is achievable with the current subset of numbers.
Way 3⚓︎
Way 4⚓︎
Hash Table Solution: