πŸš€Day 15. Partition Equal Subset Sum 🧠

The problem can be found at the following link: Question Link

πŸ’‘ Problem Description:

Given an array arr[], determine if it can be partitioned into two subsets such that the sum of elements in both parts is the same.

Each element must be in exactly one subset.

πŸ” Example Walkthrough:

Example 1:

Input:

arr = [1, 5, 11, 5]

Output:

True

Explanation:

The array can be partitioned into [1, 5, 5] and [11], both having the sum 11.

Example 2:

Input:

Output:

Explanation:

There is no way to split the array into two subsets with equal sum.

Constraints:

  • $(1 \leq arr.size \leq 100)$

  • $(1 \leq arr[i] \leq 200)$

🎯 My Approach:

Optimized 1D Dynamic Programming

Algorithm Steps:

  1. Calculate the total sum of the array. If it's odd, return false (cannot be evenly split).

  2. Use a DP table (dp[j]), where dp[j] tells if we can form sum j.

  3. Initialize dp[0] = true, since a sum of 0 is always possible.

  4. Iterate through each element in the array:

    • Update dp[j] = dp[j] OR dp[j - num] for j = target down to num.

  5. If dp[target] is true, we can partition the array into two subsets with equal sum.

πŸ•’ Time and Auxiliary Space Complexity

  • Expected Time Complexity: $O(N \times sum)$, as we iterate over the elements and process sums up to sum/2.

  • Expected Auxiliary Space Complexity: $O(sum)$, as we use a 1D DP array of size sum/2 + 1.

πŸ“ Solution Code

Code (C++)

⚑ Alternative Approaches

2️⃣ Dynamic Programming (O(NΓ—sum) Time, O(NΓ—sum) Space) β€” 2D DP

Algorithm Steps:

  1. Use a 2D DP table, where dp[i][j] represents whether a subset with sum j can be formed using the first i elements.

  2. Base Case:

    • dp[0][0] = true (sum 0 can be formed with zero elements).

    • dp[i][0] = true for all i (sum 0 is always achievable).

  3. Recurrence Relation: $[ dp[i][j] = dp[i-1][j] \quad \text{(exclude element)} $] If arr[i-1] ≀ j, then: $[ dp[i][j] = dp[i-1][j] \text{ OR } dp[i-1][j - arr[i-1]] $] (include element if possible).

βœ… Time Complexity: O(N Γ— sum) βœ… Space Complexity: O(N Γ— sum)

3️⃣ Recursive + Memoization (O(NΓ—sum) Time, O(NΓ—sum) Space)

Algorithm Steps:

  1. Define a recursive function canPartition(i, target) that checks if a subset of arr[0...i] sums up to target.

  2. Base Cases:

    • If target == 0, return true.

    • If i < 0 or target < 0, return false.

  3. Recurrence Relation:

    • Exclude arr[i]: canPartition(i - 1, target).

    • Include arr[i] if arr[i] ≀ target: canPartition(i - 1, target - arr[i]).

  4. Use Memoization (dp[i][target]) to avoid redundant calculations.

βœ… Time Complexity: O(N Γ— sum) βœ… Space Complexity: O(N Γ— sum) (recursion stack)

Comparison of Approaches

Approach

⏱️ Time Complexity

πŸ—‚οΈ Space Complexity

βœ… Pros

⚠️ Cons

1D DP (Space Optimized)

🟑 O(N Γ— sum)

🟒 O(sum/2)

Best space-efficient solution

Requires careful indexing

2D DP (Tabulation)

🟑 O(N Γ— sum)

πŸ”΄ O(N Γ— sum)

Intuitive approach

High space usage

Recursive + Memoization

🟑 O(N Γ— sum)

πŸ”΄ O(N Γ— sum)

Natural recursion flow

Stack overhead

βœ… Best Choice?

  • If optimizing space: Use 1D DP (Space-Optimized).

  • If space is not a concern: Use 2D DP (Tabulation) for easier understanding.

  • For recursion lovers: Use Recursive + Memoization.

Code (Java)

Code (Python)

🎯 Contribution and Support:

For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: Any Questions. Let’s make this learning journey more collaborative!

⭐ If you find this helpful, please give this repository a star! ⭐


πŸ“Visitor Count

Last updated