Partition Equal Subset Sum in DSA Java - 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 size grows.
How does the algorithm's work increase when the input numbers get bigger?
Analyze the time complexity of the following code snippet.
public boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
boolean[] dp = new boolean[target + 1];
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 sum.
- How many times: Outer loop runs once per number (n times), inner loop runs up to target sum (sum/2 times) for each number.
As the number of elements or the target sum grows, the work grows roughly by multiplying these two factors.
| 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 roughly with the product of the number of elements and the half sum value.
Time Complexity: O(n * sum)
This means the time needed grows with both how many numbers there are and how large their total sum is.
[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 of the numbers because the inner loop runs up to half the sum, not just the count of numbers.
Understanding this time complexity helps you explain how dynamic programming balances between input size and value range, a key skill in problem solving.
"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 array into two equal sum subsets [OK]
- Thinking the problem is about sorting the array
- Confusing equal sum subsets with duplicate elements
- Ignoring the sum condition and just checking elements
Solution
Step 1: Identify the return type
The function should return true or false, so the return type must be boolean.Step 2: Check parameter type
The input is an array of integers, so parameter should be int[] nums.Final Answer:
public boolean canPartition(int[] nums) -> Option AQuick Check:
Boolean return + int array parameter = public boolean canPartition(int[] nums) [OK]
- Using int return type instead of boolean
- Using void return type which gives no answer
- Passing single int instead of int array
int[] nums = {1, 5, 11, 5};
System.out.println(canPartition(nums));
public static boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 != 0) return false;
int target = sum / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
for (int num : nums) {
for (int i = target; i >= num; i--) {
dp[i] = dp[i] || dp[i - num];
}
}
return dp[target];
}Solution
Step 1: Calculate total sum and check parity
Sum = 1+5+11+5 = 22, which is even, so continue.Step 2: Use dynamic programming to check subset sum
The dp array tracks sums achievable. The subset {11, 5, 5} sums to 21, but target is 11. Actually, subset {11} and {1,5,5} both sum to 11, so dp[target] becomes true.Final Answer:
true -> Option CQuick Check:
Subset sum equals half total sum = true [OK]
- Not checking if total sum is even first
- Confusing dp array update direction
- Assuming subset must be contiguous
public boolean canPartition(int[] nums) {
int sum = 0;
for (int num : nums) sum += num;
if (sum % 2 == 0) return false;
int target = sum / 2;
boolean[] dp = new boolean[target + 1];
dp[0] = true;
for (int num : nums) {
for (int i = target; i >= num; i--) {
dp[i] = dp[i] || dp[i - num];
}
}
return dp[target];
}Solution
Step 1: Check sum parity condition
The code returns false if sum % 2 == 0, but it should return false if sum is odd (sum % 2 != 0).Step 2: Verify other parts
dp array size and loops are correct; only the parity check is wrong.Final Answer:
The sum parity check condition is reversed -> Option BQuick Check:
Return false if sum is odd, not even [OK]
- Returning false when sum is even instead of odd
- Changing dp array size incorrectly
- Looping forward instead of backward causing wrong dp updates
nums = {2, 2, 3, 5}, which of the following modifications to the standard Partition Equal Subset Sum approach will correctly determine if the array can be partitioned into two subsets with equal sum, considering that elements can be used multiple times?Solution
Step 1: Understand the problem change
Allowing elements multiple times means this is an unbounded subset sum problem, requiring forward iteration in dp update.Step 2: Modify dp iteration accordingly
Changing the inner loop to go from num to target (forward) allows reusing elements multiple times correctly.Step 3: Verify other options
Initializing dp[1] is incorrect; recursion without memo is inefficient; doubling target sum is wrong.Final Answer:
Change the inner loop to iterate from num to target (forward) instead of backward -> Option DQuick Check:
Unbounded subset sum needs forward dp loop [OK]
- Using backward loop for repeated elements
- Incorrect dp initialization
- Ignoring efficiency by using recursion without memo
Ready to prove it?
Pass the test and this pattern moves unknown
