Partition Equal Subset Sum in DSA C++ - Time & Space Complexity
We want to know how the time needed to check if an array can be split into two equal-sum parts grows as the array gets bigger.
How does the number of steps change when the array size or values increase?
Analyze the time complexity of the following code snippet.
bool canPartition(vector<int>& nums) {
int total = 0;
for (int num : nums) total += num;
if (total % 2 != 0) return false;
int target = total / 2;
vector<bool> dp(target + 1, false);
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; --j) {
dp[j] = dp[j] || dp[j - num];
}
}
return dp[target];
}
This code checks if the array can be split into two parts with equal sums using a dynamic programming approach.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Nested loops where the outer loop goes through each number and the inner loop goes through possible sums up to half the total.
- How many times: Outer loop runs once per number (n times), inner loop runs up to target sum (S/2) times for each number.
As the number of elements (n) or the total sum (S) grows, the steps increase roughly by n times half the sum.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 (sum ~100) | 10 * 50 = 500 |
| 100 (sum ~1000) | 100 * 500 = 50,000 |
| 1000 (sum ~10,000) | 1000 * 5000 = 5,000,000 |
Pattern observation: The operations grow linearly with the number of elements and linearly with the sum value.
Time Complexity: O(n * S)
This means the time grows proportionally to the number of elements times the total sum of the array.
[X] Wrong: "The time depends only on the number of elements (n), not on the sum of elements."
[OK] Correct: The inner loop depends on the target sum, so larger sums increase the steps even if n stays the same.
Understanding this complexity helps you explain how dynamic programming solves subset problems efficiently compared to trying all subsets.
"What if we used recursion with memoization instead of this bottom-up approach? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem statement
The problem asks whether the array can be divided into two parts where the sum of elements in both parts is the same.Step 2: Identify the key condition
This means the total sum of the array must be even, and there must be a subset with sum equal to half of the total sum.Final Answer:
If the array can be split into two subsets with equal sums -> Option AQuick Check:
Partition Equal Subset Sum = Split into equal sum subsets [OK]
- Thinking it checks for duplicates
- Assuming sorting is required
- Confusing with subset sum existence
Solution
Step 1: Choose correct data type and size
We need a boolean vector of size (sum/2 + 1) to track subset sums. std::vector<bool> dp(sum / 2 + 1, false); dp[0] = true; uses correct size and type.Step 2: Set base case correctly
dp[0] = true means sum zero is always possible. std::vector<bool> dp(sum / 2 + 1, false); dp[0] = true; does this correctly. std::vector<int> dp(sum / 2 + 1, 0); dp[0] = 1; uses int vector, which is less appropriate. std::vector<bool> dp(sum + 1, false); dp[sum] = true; uses wrong size and sets dp[sum] instead of dp[0].Final Answer:
std::vector<bool> dp(sum / 2 + 1, false); dp[0] = true; -> Option CQuick Check:
Boolean vector with dp[0] true = Correct initialization [OK]
- Using int vector instead of bool
- Incorrect dp array size
- Setting wrong base case index
{1, 5, 11, 5}?
bool canPartition(std::vector<int>& nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
std::vector<bool> dp(target + 1, false);
dp[0] = true;
for (int num : nums) {
for (int j = target; j >= num; --j) {
dp[j] = dp[j] || dp[j - num];
}
}
return dp[target];
}
int main() {
std::vector<int> nums = {1, 5, 11, 5};
std::cout << (canPartition(nums) ? "true" : "false") << std::endl;
return 0;
}Solution
Step 1: Calculate total sum and check parity
Sum = 1 + 5 + 11 + 5 = 22, which is even, so proceed.Step 2: Use DP to check subset sum of 11
The code uses a boolean dp array to check if subset sum 11 is possible. The subsets {11} and {1,5,5} both sum to 11, so dp[11] becomes true.Final Answer:
true -> Option AQuick Check:
Subset sum 11 exists = true [OK]
- Assuming sum odd means true
- Not iterating dp backwards
- Confusing output with subset elements
bool canPartition(std::vector<int>& nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
std::vector<bool> dp(target + 1, false);
dp[0] = true;
for (int num : nums) {
for (int j = num; j <= target; ++j) {
dp[j] = dp[j] || dp[j - num];
}
}
return dp[target];
}Solution
Step 1: Analyze inner loop direction
The inner loop iterates forwards, which causes dp to use updated values in the same iteration, leading to incorrect results.Step 2: Correct loop direction
Iterating backwards ensures dp[j - num] uses values from previous iteration, preserving correctness.Final Answer:
Change inner loop to iterate backwards: for (int j = target; j >= num; --j) -> Option DQuick Check:
Backward iteration in DP loop fixes state update [OK]
- Iterating dp forwards causing wrong results
- Incorrect dp initialization
- Wrong sum parity check
{2, 2, 3, 5}, which of the following statements is true regarding the Partition Equal Subset Sum problem?Solution
Step 1: Calculate total sum
Sum = 2 + 2 + 3 + 5 = 12, which is even, so partition might be possible.Step 2: Check for subset with sum 6
Half sum = 6. Possible subsets: - {2,2,3} sum = 7 (too high) - {2,3} sum = 5 (too low) - {5} sum = 5 (too low) - {2,2} sum = 4 (too low) No subset sums exactly to 6.Final Answer:
The array cannot be partitioned into two subsets with equal sum because no subset sums to half the total -> Option BQuick Check:
Half sum subset missing = No partition [OK]
- Assuming total sum even means partition possible
- Incorrect subset sums calculation
- Confusing subsets with unequal sums
Ready to prove it?
Pass the test and this pattern moves unknown
