Algorithm

Coin Change (Greedy)

Greedy & Intervals Pattern

Coin Change (Greedy)

You are given an integer amount and an array of coin denominations, each available in unlimited supply. Return the fewest coins that sum to exactly amount. This version assumes the denominations form a canonical system — one in which repeatedly taking the largest coin that fits is guaranteed to be optimal (real-world currencies like 1, 5, 10, 25 are canonical). If the amount cannot be made, return -1.

CONSTRAINTS
  • 1 ≤ amount ≤ 10⁴
  • 1 ≤ denominations.length ≤ 12
  • Every denomination is a positive integer, and the supply of each is unlimited
  • The denominations are assumed canonical, so the greedy choice is always optimal
EXAMPLE 1
Input: amount = 67, coins = [1, 5, 10, 25]
Output: 6
Two 25s, one 10, one 5 and two 1s make 67 with six coins. Because this denomination set is canonical, no combination uses fewer.
EXAMPLE 2
Input: amount = 30, coins = [1, 5, 10, 25]
Output: 2
A 25 and a 5. Greedy takes the 25 first and the single 5 follows, which is optimal here.
EXAMPLE 3
Input: amount = 11, coins = [1, 5, 10, 25]
Output: 2
A 10 and a 1. The greedy grab of the 10 leaves exactly 1, completed by a single penny.
EXAMPLE 4
Input: amount = 3, coins = [2]
Output: -1
Every total built from 2s is even, so 3 can never be formed and the contract returns -1.
EXAMPLE 5
Input: amount = 6, coins = [1, 3, 4]
Output: 2
The true minimum is two 3s. Greedy would instead take a 4 and two 1s for three coins — a wrong answer, because this set is not canonical and the greedy precondition fails.
What does 'canonical' mean, and can I always assume it?
A canonical system is one where taking the largest coin that fits is optimal for every amount. Most national currencies are canonical, but arbitrary denominations are not. Never assume it — confirm it, and if the system might be non-canonical, use the dynamic-programming version instead.
How do I know whether a given set is canonical?
There is no simple test you can eyeball. Deciding canonicity is a genuinely hard question in general, which is exactly why the safe interview default for arbitrary coins is the dynamic-programming solution that is always correct.
Is the supply of each coin unlimited?
Yes, you may use each denomination as many times as needed. A limited supply would turn this into a different, harder problem closer to the 0/1 knapsack.
What should I return when the amount cannot be made exactly?
-1. Note that greedy can also get stuck part-way on some non-canonical systems even when a solution exists, which is a second reason to prefer dynamic programming when canonicity is in doubt.
What "greedy" even means, and the trap in it

A greedy algorithm builds an answer by repeatedly making the choice that looks best right now, never reconsidering. It never looks ahead and never backtracks. When that works, it is wonderful — usually one sort and one pass. The catch, which this problem exists to teach, is that the locally best choice is not always part of a globally best answer, and greedy has no way to notice when it has gone wrong.

So the real skill in every greedy problem is not writing the loop — that part is trivial. It is proving that the greedy choice is safe. This page is where we learn to distrust greedy until we have that proof, using the friendliest possible example: making change.

The greedy rule for coins

To make an amount with the fewest coins, the obvious move is: take the largest coin that still fits, subtract it, repeat. With everyday coins 1, 5, 10, 25 and amount 30, you take a 25, then a 5 — two coins, and clearly nothing beats two here.

python
def coin_change_greedy(coins, amount):
    coins.sort(reverse=True)         # largest first
    count = 0
    for coin in coins:
        if amount == 0:
            break
        take = amount // coin        # as many of this coin as fit
        count += take
        amount -= take * coin
    return count if amount == 0 else -1

Sort is O(D log D) for D denominations, the pass is O(D), and there is no dependence on the amount at all — vastly faster than building a table.

Why it works on the coins in your pocket

It is tempting to accept "take the biggest" as obvious, but it is not obvious — it is a property of these particular denominations, and it needs an argument. Here is the shape of that argument for the 1-5-10-25 system.

Suppose the optimal solution for some amount used fewer than the greedy number of the largest coin that fits. Then it must make up the difference with smaller coins — and for a canonical system you can always show that some bundle of those smaller coins can be swapped for one larger coin without increasing the count. For instance, any optimal solution that uses five or more 1s could replace five of them with a single 5, contradicting the claim that it was optimal. Push that reasoning through every denomination and you get: the optimal solution must use exactly as many of each large coin as greedy does. That "swap small coins for a bigger one without making things worse" move is called an exchange argument, and it is the standard way to prove any greedy algorithm correct. Keep the name — it returns on every greedy page.

Where greedy quietly fails

Now the whole point. Change the denominations to [1, 3, 4] and ask for 6.

- Greedy: largest coin that fits is 4. Take it, 2 remains. Now take a 1, then another 1. Three coins.
- Optimal: two 3s. Two coins.

Greedy walked confidently off a cliff, and — this is the dangerous part — it produced a perfectly reasonable-looking wrong answer, with no error and no warning. The exchange argument above breaks for [1, 3, 4]: after taking the 4, the remaining 2 cannot be built from a single bigger coin, so the swap that made greedy safe for canonical systems is unavailable.

Crucial Notea coin system is called canonical exactly when greedy happens to be optimal for every amount, and non-canonical otherwise. There is no shortcut in the denominations that tells you at a glance which you have — deciding canonicity is itself a small research problem. So in an interview, the correct instinct is: do not assume greedy works on coins unless you are told the system is canonical. If it might not be, fall back to the dynamic-programming version, which tries every coin at every amount and is always correct (that is the other Coin Change problem in this curriculum, costing O(amount × D)).
Worked Example:amount = 67, coins = [1, 5, 10, 25]
- Largest is 25. 67 // 25 = 2, take two 25s (50). Remaining 17. Count 2.
- Next 10. 17 // 10 = 1, take one (10). Remaining 7. Count 3.
- Next 5. 7 // 5 = 1, take one. Remaining 2. Count 4.
- Next 1. 2 // 1 = 2, take two. Remaining 0. Count 6.

Six coins, and because this system is canonical the exchange argument guarantees no plan does better.

Now the cautionary run, amount = 6, coins = [1, 3, 4]: greedy returns 3, but the true minimum is 2. Same code, wrong answer — because the precondition (canonical system) does not hold.

The takeaway that outlasts coins

This problem is really a lesson about greedy in general, disguised as arithmetic. The reusable habits:

- Greedy is a claim, not a method. The loop is easy; the claim "the local best is always safe" is what needs defending. Never ship a greedy solution you cannot argue for.
- The exchange argument is your tool. To justify a greedy choice, show that any optimal solution can be rewritten to agree with the greedy choice without getting worse. If you can, greedy is safe. If the rewrite gets stuck — as it does on [1, 3, 4] — that stuck point is usually a counterexample.
- Hunt for a counterexample before trusting greedy. One small failing input settles the matter faster than any proof, and it is exactly what an interviewer wants to see you try.

Every remaining greedy problem in this section — activity selection, jump game, gas station, fractional knapsack, the interval problems — is an exercise in finding the safe greedy choice and arguing why it is safe. The arithmetic changes; the discipline does not.

Interactive Strategy Visualization

Greedy Intuition: Coin Change

Strategy: Local Optimum
Remaining Amount
67¢
Empty selection...
Goal: Make change for 67¢ using the minimum number of coins [25, 10, 5, 1].
MINDSET

A greedy algorithm makes the **best local choice** at each stage. We don't worry about the future; we just take as much value as possible *right now*.

CANONICALITY

Greedy is only correct if the coin system is **canonical**. If coins don't "cleanly" replace each other, a greedy choice might block an even better combination.

Exponential Try Every Combination
O(amount × D) Time Dynamic Programming
O(D log D) Time Greedy (canonical only)