Bird
Raised Fist0
Interview Prepdp-knapsackmediumAmazonGoogleFacebook

Partition to K Equal Sum Subsets

Choose your preparation mode4 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Steps
setup

Calculate total sum and target per bucket

Calculate the total sum of nums and determine the target sum each bucket must reach by dividing total by k.

💡 Knowing the target sum is essential because the problem reduces to checking if subsets can sum exactly to this target.
Line:total = sum(nums) if total % k != 0: return False target = total // k
💡 The problem is only solvable if total sum is divisible by k; otherwise, partitioning is impossible.
📊
Partition to K Equal Sum Subsets - Watch the Algorithm Execute, Step by Step
Watching this visualization helps you understand how bitmask DP explores all subsets efficiently and how the modulo operation tracks partial sums for equal partitions.
Step 1/15
·Active fillAnswer cell
Initializing dp array
i\w
Initializing dp array
i\w
Initializing dp array
i\w0
i=00
dp[0] = 0 (empty subset)
Initializing dp array
i\w0
i=00
Current mask = 0 (empty subset)
Item 6 - wt:1 val:1
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
i=00????????????????????????????????????????????????????????????????1
mask=0 (empty subset)
Item 2 - wt:2 val:2
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
i=00???2?????????????????????????????????????????????????????????????
mask=0 (empty subset)
Item 1 - wt:2 val:2
i\w012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
i=00?2?2????????????????????????????????????????????????????????????
mask=0 (empty subset)
Item 4 - wt:4 val:4
i\w0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
i=00?2?2???????????4???????????????????????????????????????????????
mask=0 (empty subset)
Item 3 - wt:3 val:3
i\w0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
i=00?2?2???3???????4???????????????????????????????????????????????
mask=0 (empty subset)
Item 5 - wt:3 val:3
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
i=00?2?2???3???????4???????????????????????????????3???????????
mask=0 (empty subset)
Item 0 - wt:4 val:4
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
i=0042?2???3???????4???????????????????????????????3???????????
mask=0 (empty subset)
Item 6 - wt:1 val:1
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
i=0042?2???3???????4???????????????????????????????3??????????0
mask=1 (subset {0})
Item 1 - wt:2 val:2
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
i=0042?2???3???????4???????????????????????????????3??????????0
mask=1 (subset {0})
Initializing dp array
i\w01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
i=0042323403401123440123401234012340123401234012340123401234012340123401234
DP table partially filled
Initializing dp array
i\w012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
i=004232340340112344012340123401234012340123401234012340123401234012340120
Answer cell dp[127] = 0 (partition possible)

Key Takeaways

Bitmask DP efficiently explores all subsets by representing them as integers and tracking partial sums modulo target.

This insight is hard to see from code alone because the bitmask representation and modulo arithmetic are abstract concepts.

The DP table's fill order depends on reachable subsets, ensuring no redundant computations and pruning unreachable states.

Visualizing the fill order clarifies why some subsets are never reached and how the algorithm avoids unnecessary work.

The final decision depends on whether the full set mask is reachable with sum modulo target zero, confirming equal partitioning.

Seeing the final dp cell highlighted as the answer cell concretely connects the DP state to the problem's solution.

Practice

(1/5)
1. You are given a list of positive integers and need to determine if it can be split into two subsets with equal sums. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Dynamic programming using a subset-sum style 0/1 knapsack approach to check for a subset with sum equal to half the total
B. Divide and conquer by recursively splitting the array into halves and checking sums
C. Sorting the array and using two pointers to find two subsets with equal sums
D. Greedy algorithm that picks the largest elements first until half the total sum is reached

Solution

  1. Step 1: Understand the problem requires partitioning into two equal sum subsets

    Since the problem asks if the array can be split into two subsets with equal sums, it reduces to finding a subset with sum equal to half the total sum.
  2. Step 2: Identify the algorithm that checks subset sums efficiently

    The 0/1 knapsack dynamic programming approach can determine if such a subset exists by building a DP table or array that tracks achievable sums up to half the total.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Greedy and sorting approaches fail on many inputs; DP guarantees correctness [OK]
Hint: Partition reduces to subset sum with half total [OK]
Common Mistakes:
  • Thinking greedy or sorting solves partition optimally
2. What is the time complexity of the space-optimized bottom-up 0/1 Knapsack algorithm when there are n items and the knapsack capacity is W?
medium
A. O(2^n)
B. O(n + W)
C. O(n * W)
D. O(n * log W)

Solution

  1. Step 1: Identify loops in the algorithm

    The algorithm has an outer loop over n items and an inner loop over capacities from W down to the item's weight, which can be up to W iterations.
  2. Step 2: Calculate total operations

    Multiplying the loops gives O(n * W) time complexity. Recursive brute force is exponential, and linear or logarithmic complexities are incorrect here.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Nested loops over n and W -> O(n * W) [OK]
Hint: Nested loops over items and capacity -> O(n * W) [OK]
Common Mistakes:
  • Confusing recursion stack space with time complexity.
3. The following code attempts to count the number of combinations to make change. Which line contains a subtle bug that causes it to count permutations instead of combinations?
medium
A. Line 5: inner loop iterating backwards over amounts
B. Line 4: outer loop over coins
C. Line 2: dp initialization
D. Line 6: updating dp[w] with dp[w - coin]

Solution

  1. Step 1: Understand iteration order effect

    Iterating amounts backwards causes dp to count permutations, not combinations.
  2. Step 2: Identify bug line

    Line 5 iterates w from amount down to coin, which breaks combination counting logic.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Forward iteration over amounts is required to count combinations correctly [OK]
Hint: Check direction of inner loop iteration [OK]
Common Mistakes:
  • Using backward iteration in 1D dp
  • Misplacing dp[0] initialization
4. The following code attempts to solve the coin change minimum coins problem. Identify the line containing the subtle bug that causes incorrect results or infinite recursion for amount=0.
def coinChange(coins, amount):
    def dfs(rem):
        if rem == 0:
            return 0
        res = float('inf')
        for coin in coins:
            if rem - coin >= 0:
                res = min(res, 1 + dfs(rem - coin))
        return res
    ans = dfs(amount)
    return ans if ans != float('inf') else -1
medium
A. Line 3: Missing base case for rem < 0
B. Line 6: Missing check for rem == 0 before recursion
C. Line 9: Returning res without checking if res is still infinity
D. Line 7: Incorrect condition rem - coin >= 0 instead of rem >= coin

Solution

  1. Step 1: Analyze base cases in recursion

    Code handles rem == 0 but lacks base case for rem < 0, but since rem - coin >= 0 check prevents negative rem, no infinite recursion occurs.
  2. Step 2: Check return value correctness

    Returning res directly without checking if res is still infinity can cause incorrect results when no valid coin combination exists.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Must check if res is infinity before returning to handle no solution cases correctly [OK]
Hint: Check if result is infinity before returning in recursion [OK]
Common Mistakes:
  • Forgetting to handle no solution case
  • Assuming rem == 0 base case suffices
5. Suppose the problem is modified so that each coin can be used at most once (0/1 knapsack variant). Which of the following changes to the original code correctly counts the number of combinations?
hard
A. Change inner loop to iterate amounts backward (from amount down to coin) to avoid reuse
B. Change inner loop to iterate amounts forward (from coin to amount) as in original code
C. Use recursion without memoization to explore all subsets
D. Use greedy approach picking largest coins first

Solution

  1. Step 1: Understand 0/1 knapsack constraints

    Each coin can be used once, so dp updates must avoid reuse within same iteration.
  2. Step 2: Identify correct iteration order

    Iterating amounts backward ensures dp[w] uses dp[w - coin] from previous iteration, preventing reuse.
  3. Step 3: Evaluate other options

    Forward iteration allows reuse; recursion without memoization is inefficient; greedy is incorrect.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Backward iteration is standard for 0/1 knapsack to avoid reuse [OK]
Hint: Backward iteration prevents reuse in 0/1 knapsack [OK]
Common Mistakes:
  • Using forward iteration causing reuse
  • Relying on greedy or naive recursion