Bird
Raised Fist0
Interview Prepdp-knapsackmediumAmazonGoogleMicrosoftBloomberg

Coin Change (Minimum Coins)

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

Initialize dp array

Create a dp array of size amount+1 (12) filled with infinity to represent unreachable amounts, except dp[0] which is 0 since zero coins are needed to make amount zero.

💡 Setting dp[0] = 0 anchors the solution, showing that no coins are needed to make amount zero.
Line:dp = [float('inf')] * (amount + 1) dp[0] = 0
💡 This initialization sets the base case and marks all other amounts as initially unreachable.
📊
Coin Change (Minimum Coins) - Watch the Algorithm Execute, Step by Step
Watching the dp array update step-by-step reveals how the algorithm builds solutions from smaller amounts to larger amounts, making the abstract code concrete.
Step 1/21
·Active fillAnswer cell
Initializing dp array
i\w01234567891011
i=00
dp[0] = 0 (base case)
Item 0 - wt:1 val:1
i\w01234567891011
i=00
Computing dp[1]
Item 0 - wt:1 val:1
i\w01234567891011
i=001
dp[1] updated to 1
Item 1 - wt:2 val:1
i\w01234567891011
i=001
dp[1] unchanged
Item 2 - wt:5 val:1
i\w01234567891011
i=001
dp[1] unchanged
Item 0 - wt:2 val:2
i\w01234567891011
i=001
Computing dp[2]
Item 0 - wt:1 val:2
i\w01234567891011
i=0012
dp[2] updated to 2
Item 1 - wt:2 val:1
i\w01234567891011
i=0011
dp[2] updated to 1
Item 2 - wt:5 val:1
i\w01234567891011
i=0011
dp[2] unchanged
Item 0 - wt:3 val:
i\w01234567891011
i=0011
Computing dp[3]
Item 2 - wt:5 val:
i\w01234567891011
i=0011
dp[3] unchanged
Item 0 - wt:5 val:
i\w01234567891011
i=0011
Computing dp[5]
Item 2 - wt:5 val:1
i\w01234567891011
i=00111
dp[5] updated to 1
Item 0 - wt:6 val:
i\w01234567891011
i=00111
Computing dp[6]
Item 0 - wt:10 val:
i\w01234567891011
i=00111
Computing dp[10]
Item 2 - wt:5 val:2
i\w01234567891011
i=001112
dp[10] updated to 2
Item 0 - wt:11 val:
i\w01234567891011
i=001112
Computing dp[11]
Item 0 - wt:1 val:3
i\w01234567891011
i=0011123
dp[11] updated to 3
Item 1 - wt:2 val:3
i\w01234567891011
i=0011123
dp[11] unchanged
Item 2 - wt:5 val:3
i\w01234567891011
i=0011123
dp[11] unchanged
Initializing dp array
i\w01234567891011
i=0011123
Answer: 3 coins

Key Takeaways

The dp array builds solutions incrementally from smaller amounts to larger amounts.

This is hard to see from code alone because the dp updates happen inside nested loops without explicit visualization.

Each dp[i] depends on dp[i - coin] for all coins that fit, showing the unbounded knapsack pattern.

Visualizing dependencies clarifies why order and coin choices matter.

Larger coins can drastically improve dp values when they fit exactly, as seen with coin 5 at amounts 5 and 10.

This concrete example shows how the algorithm finds better solutions by trying all coins.

Practice

(1/5)
1. You are given a set of positive integers and need to partition it into two subsets such that the absolute difference of their sums is minimized. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. Greedy algorithm that sorts and assigns elements alternately to subsets
B. Dynamic programming using a subset-sum style approach to find achievable sums
C. Divide and conquer by recursively splitting the array into halves
D. Sorting and then pairing elements from opposite ends to balance sums

Solution

  1. Step 1: Understand problem constraints

    The problem requires minimizing the difference between sums of two subsets, which is a classic partition problem variant.
  2. Step 2: Identify algorithmic pattern

    Greedy or divide-and-conquer approaches do not guarantee minimal difference. Dynamic programming, specifically subset-sum style DP, can find all achievable sums up to total_sum, enabling minimal difference calculation.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    DP subset-sum approach guarantees optimal partition [OK]
Hint: Minimal difference requires subset-sum DP, not greedy [OK]
Common Mistakes:
  • Assuming greedy or sorting suffices for minimal difference
2. You are given a list of positive integers and a target sum. You need to determine if there exists a subset of these integers that sums exactly to the target. Which algorithmic approach guarantees an optimal solution for this problem?
easy
A. A greedy algorithm that picks the largest numbers first until the sum is reached or exceeded.
B. A dynamic programming approach that builds a boolean table tracking achievable sums up to the target.
C. A depth-first search that tries all subsets without memoization.
D. A sorting-based two-pointer technique to find pairs that sum to the target.

Solution

  1. Step 1: Understand problem constraints

    The problem requires checking if any subset sums exactly to a target, which is a classic subset sum problem.
  2. Step 2: Identify algorithm that guarantees correctness

    Greedy and two-pointer approaches fail because they do not consider all subsets. DFS without memoization is correct but inefficient. Dynamic programming builds a table of achievable sums, ensuring all subsets are considered efficiently.
  3. Final Answer:

    Option B -> Option B
  4. Quick Check:

    DP tracks all sums up to target -> correct [OK]
Hint: Subset sum requires DP to track achievable sums [OK]
Common Mistakes:
  • Thinking greedy or sorting solves subset sum optimally
3. The following code attempts to solve the job scheduling problem optimally. Which line contains a subtle bug that can cause incorrect results?
medium
A. Line 11: Using bisect_right to find compatible job index
B. Line 7: Creating ends array from job end times
C. Line 4: Sorting jobs by start time instead of end time
D. Line 14: Calculating dp[i] as max of take and skip

Solution

  1. Step 1: Identify sorting criteria

    Jobs must be sorted by end time for binary search on ends array to work correctly.
  2. Step 2: Check sorting line

    Line 4 sorts by start time, breaking DP dependencies and binary search correctness.
  3. Final Answer:

    Option C -> Option C
  4. Quick Check:

    Sorting by start time causes incorrect compatible job lookups and suboptimal profits [OK]
Hint: Sort jobs by end time, not start time [OK]
Common Mistakes:
  • Sorting by start time
  • Incorrect binary search bounds
  • Ignoring dp base cases
4. The following code attempts to solve the minimum subset sum difference problem using space-optimized DP. Identify the line containing the subtle bug that causes incorrect results on some inputs.
medium
A. Line 4: dp initialization without dp[0] = true
B. Line 6: Outer loop iterating over elements
C. Line 7: Inner loop iterating backwards from total_sum
D. Line 11: Returning difference using total_sum and w

Solution

  1. Step 1: Check base case initialization

    dp[0] must be true to represent sum zero achievable with empty subset; missing this causes no sums to be marked achievable.
  2. Step 2: Verify other lines

    Loops and return statement are correct; only missing dp[0] initialization breaks correctness.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Without dp[0] = true, dp array never updates correctly [OK]
Hint: dp[0] = true is essential base case [OK]
Common Mistakes:
  • Forgetting dp[0] initialization
  • Using forward iteration causing overcounting
5. Suppose the problem changes so that you can use each item an unlimited number of times (unbounded knapsack). Which modification to the space-optimized bottom-up DP code correctly solves this variant?
hard
A. Change the inner loop to iterate forwards from weights[i] up to W.
B. Add memoization to the recursive solution to avoid recomputation.
C. Change the inner loop to iterate backwards from W down to weights[i].
D. Use a greedy approach selecting items with the highest value-to-weight ratio repeatedly.

Solution

  1. Step 1: Understand difference between 0/1 and unbounded knapsack

    In unbounded knapsack, items can be chosen multiple times, so dp[w] can be updated using dp[w - weights[i]] from the same iteration.
  2. Step 2: Identify correct iteration order

    Iterating forwards from weights[i] to W allows reuse of updated dp values within the same iteration, enabling multiple counts of the same item.
  3. Step 3: Why other options fail

    Backward iteration prevents multiple usage in one iteration (wrong for unbounded). Memoization helps but is not the direct fix. Greedy fails for 0/1 and unbounded knapsack except fractional case.
  4. Final Answer:

    Option A -> Option A
  5. Quick Check:

    Forward iteration enables unlimited item reuse [OK]
Hint: Unbounded knapsack requires forward iteration in dp updates [OK]
Common Mistakes:
  • Using backward iteration from 0/1 knapsack causes incorrect results.