Bird
Raised Fist0
Interview Prepdp-knapsackmediumAmazonGoogle

Minimum Subset Sum Difference

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
📋
Problem

Imagine you have a set of weights and want to split them into two groups so that the difference in their total weights is as small as possible. This helps in balancing loads or dividing tasks evenly.

Given an array of positive integers, partition the array into two subsets such that the absolute difference between the sums of the subsets is minimized. Return this minimum difference.

1 ≤ n ≤ 1001 ≤ arr[i] ≤ 1000
Edge cases: Single element array → difference equals that elementAll elements equal → difference is 0 if even count, else element valueArray with one very large element and small others → difference close to large element
</>
IDE
def min_subset_sum_diff(arr: list[int]) -> int:public int minSubsetSumDiff(int[] arr)int minSubsetSumDiff(vector<int> &arr)function minSubsetSumDiff(arr)
def min_subset_sum_diff(arr):
    # Write your solution here
    pass
class Solution {
    public int minSubsetSumDiff(int[] arr) {
        // Write your solution here
        return 0;
    }
}
#include <vector>
using namespace std;

int minSubsetSumDiff(vector<int> &arr) {
    // Write your solution here
    return 0;
}
function minSubsetSumDiff(arr) {
    // Write your solution here
}
0/9
Common Bugs to Avoid
Wrong: 0Greedy approach incorrectly assumes perfect partition possible.Replace greedy logic with DP subset sum approach to find closest sum to half total sum.
Wrong: 0Unbounded knapsack logic allowing multiple uses of same element.Enforce 0/1 knapsack constraint by indexing items and not reusing them in DP.
Wrong: Wrong minimal difference (e.g., 0 or 1 instead of 2)Off-by-one error in DP indexing or boundary conditions.Carefully check DP table indices and transitions to cover all subsets correctly.
Wrong: Non-zero for empty arrayMissing base case for empty input.Add base case to return 0 if input array is empty.
Wrong: Wrong value for single element arrayNot handling single element base case properly.Return the single element value if array length is 1.
Test Cases
t1_01basic
Input{"arr":[1,6,11,5]}
Expected1

One optimal partition is {1, 5, 6} and {11} with sums 12 and 11, difference is 1.

t1_02basic
Input{"arr":[3,1,4,2,2]}
Expected0

Partition {3,4} and {1,2,2} both sum to 7, difference is 0.

t2_01edge
Input{"arr":[]}
Expected0

Empty array means no elements, difference is 0.

t2_02edge
Input{"arr":[7]}
Expected7

Single element array difference equals that element as one subset is empty.

t2_03edge
Input{"arr":[5,5,5,5]}
Expected0

All elements equal and even count, can partition into equal sums, difference 0.

t3_01corner
Input{"arr":[1,2,5,10,11]}
Expected1

Greedy approach fails here; optimal partition difference is 1.

t3_02corner
Input{"arr":[2,2,2,2,2]}
Expected2

0/1 knapsack constraint test: each element used once; difference is 2.

t3_03corner
Input{"arr":[1,3,3,9]}
Expected2

Off-by-one error test: minimal difference is 2, not 0 or 1.

t4_01performance
Input{"_description":"n=100 at constraint boundary - executor generates this"}
⏱ Performance - must finish in 2000ms

n=100, total sum up to 100000, DP O(n*sum) must complete within 2 seconds.

Practice

(1/5)
1. You need to split a positive integer n into at least two positive integers such that the product of these integers is maximized. Which algorithmic approach guarantees finding the optimal solution efficiently?
easy
A. Pure brute force recursion exploring all partitions without memoization
B. A greedy approach that always cuts the integer into 3s and 2s
C. Dynamic programming using bottom-up tabulation with state representing maximum product for each integer up to n
D. Divide and conquer by splitting the integer into two halves recursively without caching results

Solution

  1. Step 1: Understand problem structure

    The problem requires maximizing product by splitting an integer into parts, which naturally fits a DP approach where subproblems represent maximum product for smaller integers.
  2. Step 2: Evaluate options

    Greedy (always cutting 3s) fails on some inputs; brute force recursion is correct but inefficient; divide and conquer without memoization repeats work. Bottom-up DP tabulation efficiently computes all subproblems and combines results.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    DP tabulation ensures optimal substructure and overlapping subproblems [OK]
Hint: DP tabulation handles overlapping subproblems optimally [OK]
Common Mistakes:
  • Believing greedy always works for integer break
  • Ignoring memoization in recursion
2. Given the following code, what is the output when coins = [1, 2, 5] and amount = 5?
def count_ways_space_opt(coins, amount):
    dp = [0] * (amount + 1)
    dp[0] = 1
    for coin in coins:
        for w in range(coin, amount + 1):
            dp[w] += dp[w - coin]
    return dp[amount]

coins = [1, 2, 5]
amount = 5
print(count_ways_space_opt(coins, amount))
easy
A. 4
B. 7
C. 5
D. 6

Solution

  1. Step 1: Trace dp array updates for each coin

    Start dp = [1,0,0,0,0,0]. After coin=1, dp = [1,1,1,1,1,1]. After coin=2, dp = [1,1,2,2,3,3]. After coin=5, dp = [1,1,2,2,3,6].
  2. Step 2: Confirm dp[5] value

    dp[5] = 6, representing 6 ways to make amount 5 with coins [1,2,5].
  3. Final Answer:

    Option D -> Option D
  4. Quick Check:

    Manual dp tracing matches output 6 [OK]
Hint: DP accumulates counts incrementally per coin [OK]
Common Mistakes:
  • Off-by-one in dp indexing
  • Miscounting after last coin iteration
  • Confusing permutations with combinations
3. What is the time complexity of the space-optimized bottom-up dynamic programming solution for counting the number of ways to make change with n coins and amount W?
medium
A. O(n * W) because for each coin we iterate over all amounts up to W
B. O(n + W) because we iterate over coins and amounts separately
C. O(W^n) due to nested loops over coins and amounts
D. O(n * W) plus O(W) auxiliary space for the dp array

Solution

  1. Step 1: Identify loops and their ranges

    Outer loop runs n times (coins), inner loop runs up to W (amount), so time is O(n * W).
  2. Step 2: Consider space usage

    DP array size is W+1, so auxiliary space is O(W). Total complexity includes both time and space, but time complexity is the main focus here.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Time O(n*W) matches DP approach [OK]
Hint: Time is product of coins and amount; space is dp array size [OK]
Common Mistakes:
  • Confusing time with space complexity
  • Forgetting auxiliary space for dp array
  • Mistaking exponential complexity for DP
4. The following code attempts to solve the Target Sum problem using bottom-up DP with offset indexing. Which line contains a subtle bug that causes incorrect results on inputs containing zero?
medium
A. Line 12-15: Updating dp array in-place instead of using a separate next_dp
B. Line 6: dp[offset] = 1
C. Line 10: if dp[s] != 0:
D. Line 8: for num in nums:

Solution

  1. Step 1: Identify DP update method

    The code updates dp in-place during iteration over sums, causing double counting when num=0 or overlapping states.
  2. Step 2: Understand impact on zero values

    Zero does not change sum, so updating dp in-place doubles counts incorrectly. Using a separate next_dp array avoids this.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    In-place updates cause state reuse within iteration, breaking correctness [OK]
Hint: In-place dp updates cause double counting with zero values [OK]
Common Mistakes:
  • Not using a separate dp array for next iteration
5. Suppose the coin change problem is modified so that each coin can only be used at most once (0/1 knapsack variant). Which of the following changes to the bottom-up DP approach correctly solves this variant?
hard
A. Use a 2D dp array where dp[i][j] represents minimum coins to make amount j using first i coins, iterating coins outer and amounts inner
B. Sort coins and greedily pick largest coins without repetition until amount is reached
C. Keep the same 1D dp array and iterate coins inside the amount loop as before (unbounded usage)
D. Use the same 1D dp but iterate amounts outer and coins inner, updating dp[j] only if dp[j - coin] was from previous iteration

Solution

  1. Step 1: Understand the 0/1 usage constraint

    Each coin can be used once, so we must track usage per coin, requiring 2D dp.
  2. Step 2: Identify correct DP structure

    2D dp with dp[i][j] = min coins to make j using first i coins ensures no reuse; iterate coins outer, amounts inner.
  3. Step 3: Why other options fail

    Keep the same 1D dp array and iterate coins inside the amount loop as before (unbounded usage) allows unlimited reuse; B is greedy and incorrect; D misuses 1D dp which is for unbounded usage.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    0/1 knapsack requires 2D dp to track coin usage [OK]
Hint: 0/1 knapsack needs 2D dp to prevent reuse [OK]
Common Mistakes:
  • Using unbounded knapsack DP for 0/1 problem
  • Assuming greedy works for minimum coins