Choosing coins with least or no change given
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Choosing coins with the least or no change given is a classic problem in computer science and mathematics known as the "coin change problem." The goal is to find the minimum number of coins needed to make up a certain amount, or equivalently, to determine how to give change using the fewest coins possible. This article covers two fundamental approaches: the greedy algorithm and dynamic programming, with worked examples and complexity analysis.
The Coin Change Problem
Given a set of coin denominations and a target amount, find the minimum number of coins that sum to exactly that amount. If no combination works, the problem has no solution.
Greedy Algorithm
The greedy algorithm works by always choosing the largest denomination that does not exceed the remaining amount. It is fast and intuitive but only works correctly for certain denomination sets.
Example: Make 87 cents using U.S. coins (1, 5, 10, 25, 50):
- Choose 1 x 50-cent coin. Remaining: 37 cents.
- Choose 1 x 25-cent coin. Remaining: 12 cents.
- Choose 1 x 10-cent coin. Remaining: 2 cents.
- Choose 2 x 1-cent coins. Remaining: 0 cents.
Total: 5 coins.
The greedy algorithm works for U.S. coins because the denominations are designed so that the greedy choice is always optimal. However, it fails for arbitrary denomination sets. For example, with denominations [1, 3, 4] and target 6, the greedy approach picks 4 + 1 + 1 = 3 coins, but the optimal answer is 3 + 3 = 2 coins.
Dynamic Programming
Dynamic programming (DP) finds the true minimum for any set of denominations by building up solutions from smaller subproblems.
Formulation: Define as the minimum number of coins needed to make amount . The recurrence is:
where is the set of available denominations and .
Base case: (zero coins needed for amount zero).
Procedure:
- Initialize and for all from 1 to the target amount.
- For each amount from 1 to the target, try each denomination and take the minimum.
- The answer is . If it remains , no solution exists.
Worked Example
Denominations: [1, 3, 4], target: 6.
| Amount | Best using 1 | Best using 3 | Best using 4 | |
| 0 | - | - | - | 0 |
| 1 | - | - | 1 | |
| 2 | - | - | 2 | |
| 3 | - | 1 | ||
| 4 | 1 | |||
| 5 | 2 | |||
| 6 | 2 |
Result: , achieved by using two 3-cent coins.
Implementation
Comparison Table
| Property | Greedy Algorithm | Dynamic Programming |
| Correctness | Only for certain denomination sets | Always correct |
| Time Complexity | where = number of denominations | where = target amount |
| Space Complexity | ||
| Implementation | Simple | Moderate |
| When to use | Standard currency denominations | Arbitrary denomination sets |
Variations
Counting All Combinations
Instead of finding the minimum number of coins, you may need to count how many distinct ways exist to make the target amount. The recurrence changes to a sum instead of a minimum:
Tracking Which Coins Were Used
To reconstruct the actual coin selection (not just the count), maintain a separate array that records which denomination was used at each step. Then trace back from to build the list.
Common Pitfalls
- Assuming the greedy algorithm always works. It fails for denominations like
[1, 3, 4]and can even fail for[1, 15, 25]with target 30 (greedy gives 25+1+1+1+1+1 = 6 coins, optimal is 15+15 = 2 coins). - Forgetting to handle the "no solution" case when remains infinity.
- Using signed integer types without checking for overflow when initializing with a large sentinel value.
Conclusion
The coin change problem is a fundamental exercise in algorithmic thinking. The greedy approach is fast and works for well-designed currency systems, but dynamic programming provides a guaranteed-optimal solution for any set of denominations. Understanding both approaches, and knowing when greedy fails, is essential for algorithm design and technical interviews.

