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 length or sum increases?
Analyze the time complexity of the following code snippet.
bool canPartition(int* nums, int numsSize) {
int sum = 0;
for (int i = 0; i < numsSize; i++) {
sum += nums[i];
}
if (sum % 2 != 0) return false;
int target = sum / 2;
bool dp[target + 1];
memset(dp, 0, sizeof(dp));
dp[0] = true;
for (int i = 0; i < numsSize; i++) {
for (int j = target; j >= nums[i]; j--) {
dp[j] = dp[j] || dp[j - nums[i]];
}
}
return dp[target];
}
This code checks if the array can be split into two parts with equal sums using a dynamic programming approach.
- Primary operation: Nested loops where the outer loop runs over each number and the inner loop runs over possible sums up to half the total sum.
- How many times: Outer loop runs
ntimes (array length), inner loop runs up tosum/2times.
As the array size n or the sum sum grows, the number of operations grows roughly by multiplying these two.
| Input Size (n) | Approx. Operations (sum/2) |
|---|---|
| 10 | 10 * (sum/2) |
| 100 | 100 * (sum/2) |
| 1000 | 1000 * (sum/2) |
Pattern observation: The time grows linearly with the number of elements and linearly with the half sum value.
Time Complexity: O(n * sum)
This means the time needed grows proportionally with both the number of elements and the total sum of the array.
[X] Wrong: "The time depends only on the number of elements, so it is O(n)."
[OK] Correct: The time also depends on the sum value because the inner loop runs up to half the sum, so ignoring sum underestimates the time.
Understanding this time complexity helps you explain how dynamic programming solves subset problems efficiently compared to checking 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 given array can be divided into two parts where the sum of elements in both parts is the same.Step 2: Identify the key requirement
We need to check if there exists a subset whose sum is half of the total sum of the array.Final Answer:
If the array can be split into two subsets with equal sums -> Option CQuick Check:
Partition Equal Subset Sum = Split array equally [OK]
- Thinking the problem is about sorting
- Checking for duplicates instead of sums
- Assuming all numbers must be positive
Solution
Step 1: Identify correct C syntax for boolean arrays
In C,boolis available viastdbool.hand arrays are declared asbool dp[size];.Step 2: Check options for correctness
bool dp[sum+1]; uses correct syntax. int dp[sum+1]; uses int, which is not boolean. bool dp = new bool[sum+1]; uses Java/C++ style dynamic allocation, not valid in C. boolean dp[sum+1]; uses 'boolean' which is not a C keyword.Final Answer:
bool dp[sum+1]; -> Option DQuick Check:
Usebool dp[size];in C [OK]
- Using 'boolean' instead of 'bool' in C
- Trying Java-style dynamic allocation in C
- Using int instead of bool for DP array
nums = {1, 5, 11, 5}?
#include
#include
bool canPartition(int* nums, int numsSize) {
int sum = 0;
for (int i = 0; i < numsSize; i++) sum += nums[i];
if (sum % 2 != 0) return false;
int target = sum / 2;
bool dp[target + 1];
for (int i = 0; i <= target; i++) dp[i] = false;
dp[0] = true;
for (int i = 0; i < numsSize; i++) {
for (int j = target; j >= nums[i]; j--) {
dp[j] = dp[j] || dp[j - nums[i]];
}
}
return dp[target];
}
int main() {
int nums[] = {1, 5, 11, 5};
printf("%d\n", canPartition(nums, 4));
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 equals 11
The DP array tracks sums achievable. The subset {11} and {1,5,5} both sum to 11, so dp[11] becomes true.Final Answer:
1 -> Option AQuick Check:
Subset sum exists = 1 [OK]
- Not checking if total sum is even
- Incorrect DP initialization
- Looping forward instead of backward in DP
bool canPartition(int* nums, int numsSize) {
int sum = 0;
for (int i = 0; i < numsSize; i++) sum += nums[i];
if (sum % 2 != 0) return false;
int target = sum / 2;
bool dp[target + 1];
for (int i = 0; i < target; i++) dp[i] = false;
dp[0] = true;
for (int i = 0; i < numsSize; i++) {
for (int j = target; j >= nums[i]; j--) {
dp[j] = dp[j] || dp[j - nums[i]];
}
}
return dp[target];
}Solution
Step 1: Check dp array initialization loop
The loop runs from 0 to target-1, missing dp[target] initialization, which should be set to false.Step 2: Correct the loop to include target index
Change loop condition to i <= target to initialize all dp elements properly.Final Answer:
Loop initializing dp should run till target inclusive -> Option AQuick Check:
Initialize dp array fully including dp[target] [OK]
- Forgetting to initialize dp[target]
- Running inner loop forward causing wrong results
- Setting dp[0] to false instead of true
nums = {2, 2, 3, 5}, which of the following modifications will correctly determine if it can be partitioned into two subsets with equal sum using dynamic programming?Solution
Step 1: Understand limitations of 1D DP for some cases
1D DP works but 2D DP is clearer and handles subset sums by tracking elements used.Step 2: Use 2D DP where dp[i][j] shows if sum j is possible using first i elements
This approach explicitly considers each element and sum, making it easier to debug and understand.Step 3: Sorting or counting subsets is not necessary or sufficient
Sorting doesn't affect subset sums. Counting subsets is more complex and not required for yes/no answer.Final Answer:
Use a 2D DP array where dp[i][j] means if sum j is possible with first i elements -> Option BQuick Check:
2D DP tracks sums per element [OK]
- Sorting array expecting it to solve partition
- Counting subsets instead of checking existence
- Only checking largest element against half sum
Ready to prove it?
Pass the test and this pattern moves unknown
