Greedy Algorithms · Greedy Fundamentals

Greedy Denomination Coins

Always using the largest denomination that still fits, for currency systems specifically designed so that this never produces a suboptimal count.

  • 5 min read
  • 9 practice questions
  • 2 graded problems
On this page
  1. Description
  2. The approach
  3. A second flavor: limited supply
  4. Where you'll see it
  5. Which tool for which job?
  6. Common mistakes
  7. Check yourself
  8. Key takeaways
  9. Quick revise
  10. Practice

Description

Make an amount with the fewest coins and notes. For everyday currencies, "take the biggest note that fits, repeat" is exactly right - but it's a property of the particular denominations, not of the method, and it's easy to apply where it quietly fails.

This skill covers largest-first change done with division, how to recognize the coin sets where it is safe, and the limited-supply version where even a familiar currency can trap it. When greedy isn't safe, the fallback is dynamic programming.

We'll go from simple to more technical:

  1. The pattern: largest denomination first, taking as many as fit with one division.
  2. A second flavor: limited supply (Lemonade Change, an ATM) and keeping the flexible coins.
  3. Where largest-first shows up (cash registers, dispensers, formatting durations and sizes).
  4. What breaks it: non-canonical coin sets, limited stock, subtracting one coin at a time.

The approach

Java

int minCoins(int amount) {
    int[] denominations = {200, 100, 50, 20, 10, 5, 2, 1};   // euros, largest first
    int count = 0;
    for (int d : denominations) {
        count += amount / d;       // as many of this note as fit
        amount %= d;
    }
    return count;
}

Python

def min_coins(amount: int) -> int:
    count = 0
    for d in [200, 100, 50, 20, 10, 5, 2, 1]:   # euros, largest first
        used, amount = divmod(amount, d)             # as many of this note as fit
        count += used
    return count

Using division instead of subtracting one note at a time keeps it O(number of denominations) even for 10^9 (5,000,000 notes of 200 euros). The euro set is canonical: greedy matches the true minimum for every amount - checked by DP for every amount up to 5,000, far past the point where a counterexample would have to appear. So are 1, 5, 10, 25. But with coins 1, 3 and 4, greedy pays 6 as 4 + 1 + 1 (three coins) instead of 3 + 3 (two). For an arbitrary set, the fewest-coins problem needs dynamic programming.

A second flavor: limited supply

A till or an ATM doesn't have unlimited notes, and then even a canonical system can trap greedy. Lemonade costs 5; customers pay with 5, 10 or 20, in order, and you start with no change:

Java

boolean lemonadeChange(int[] bills) {
    int fives = 0, tens = 0;
    for (int b : bills) {
        if (b == 5) {
            fives++;
        } else if (b == 10) {
            if (fives == 0) return false;
            fives--;
            tens++;
        } else {                                              // 20 needs 15 back
            if (tens > 0 && fives > 0) { tens--; fives--; }   // prefer 10 + 5: fives are needed for every change
            else if (fives >= 3) fives -= 3;
            else return false;
        }
    }
    return true;
}

Python

def lemonade_change(bills: list[int]) -> bool:
    fives = tens = 0
    for b in bills:
        if b == 5:
            fives += 1
        elif b == 10:
            if fives == 0:
                return False
            fives -= 1
            tens += 1
        else:                                        # 20 needs 15 back
            if tens > 0 and fives > 0:               # prefer 10 + 5: fives are needed for every change
                tens -= 1
                fives -= 1
            elif fives >= 3:
                fives -= 3
            else:
                return False
    return True

Fives can make any change and tens can't, so spend a ten when you can. Paying 15 as three fives first fails on 5, 5, 5, 5, 10, 20, 10: after the 20, no five is left for the final 10. The same trap hits an ATM: to pay 60 holding one 50 and three 20s, "largest first" takes the 50 and then can't make 10, while 20 + 20 + 20 works.

Where you'll see it

Cash registers and change calculators use greedy because national currencies are designed to be canonical. Dispensers with a limited stock of each note need to check feasibility (or search) rather than trust plain greedy. The same "largest unit first" formats durations ("1h 2m 5s") and file sizes.

Which tool for which job?

You needUse
Fewest coins, a real currencylargest first, with division
Fewest coins, any coin setDP over amounts
Is this coin set safe for greedy?compare greedy with DP below the two largest coins' sum
Change from a limited tillkeep the flexible coins, or search/DP with counts
Fewest coins for a huge amounttake largest coins down to a small remainder, then DP

Common mistakes

MistakeWhat happensDo this instead
Greedy on any coin set1, 3, 4 pays 6 with three coins instead of twocheck the set is canonical, or use DP
Largest first with limited notesone 50 and three 20s can't pay 60prefer change that keeps options, or search
Three fives for a 20 at the lemonade standno five left for the next 10give 10 + 5 when you can
Subtracting one coin at a timeO(amount) stepsamount / d and amount % d

Check yourself

Try to answer before opening each one - recalling beats re-reading.

1. Why does greedy make 6 badly with coins 1, 3 and 4?

Show answer

It takes the largest coin, 4, and must finish with 1 + 1: three coins. 3 + 3 uses two. Greedy is only optimal for canonical systems; arbitrary ones need DP.

2. In Lemonade Change, why give 10 + 5 for a 20 rather than 5 + 5 + 5?

Show answer

A five can be used for any change and a ten only for a 20. Keeping fives keeps options open: on 5, 5, 5, 5, 10, 20, 10, paying the 20 with three fives leaves nothing for the last 10.

3. Why compute amount / d instead of subtracting d repeatedly?

Show answer

Division takes all the notes of one denomination in one step, so the loop runs once per denomination. Subtracting one at a time costs one step per note - 5,000,000 steps for 10^9 - and far more for a set whose largest coin is small.

Key takeaways

  • Largest-first change is optimal only for canonical denominations; check with DP below the two largest coins' sum.
  • For arbitrary denominations, fewest coins is DP.
  • With limited supply, greedy can fail even for canonical systems - keep flexible coins.
  • Divide, don't subtract one coin at a time.

Quick revise

The whole skill on one page, for the night before an interview.

This page puts the lesson and the deep dive together. Skim it before practice or an interview, and go back to the full lesson for anything you don't recognize.

Pick the tool

You needUse
Real currencylargest first, divide
Any coin setDP
Is greedy safe?DP below the two largest coins' sum
Limited tillkeep flexible coins, or a DP with counts
Huge amountlargest coins to ~c_max^2, then DP

Snippets worth knowing by heart

Java

int count = 0;
for (int d : denominations) {          // largest first
    count += amount / d;
    amount %= d;
}

Python

best = [0] + [float("inf")] * amount   # any coin set: DP
for a in range(1, amount + 1):
    best[a] = min((best[a - c] + 1 for c in coins if c <= a), default=float("inf"))

The traps

  • Greedy on a non-canonical set: coins 1, 3, 4 pay 6 with three coins, not two. Check the set, or use DP.
  • Largest first with limited notes: one 50 and three 20s can't pay 60 that way. Prefer change that keeps options, or search.
  • Spending fives you'll need later: giving three fives for a 20 leaves none for the next 10. Give 10 + 5 when you can.
  • Subtracting one coin at a time: that's O(amount) steps. Use amount / d and amount % d.

Staff-level points, one line each

  • Kozen-Zaks: the smallest counterexample lies below the two largest coins' sum (it held for all 220 non-canonical random sets).
  • Pearson's O(n^3) test found the same smallest counterexample on 300 sets.
  • Adding a 20 to US coins breaks them: 40 is 3 coins by greedy, 2 at best.
  • Coins 1, 50, 51 for 100: greedy 50 coins, best 2. There is no constant-factor guarantee.
  • Huge amounts: fewer than c_max non-largest coins are needed; 10^15 with 1, 5, 12, 19 took a DP over 370 amounts.
  • Limited supply is a bounded knapsack.

Say it in an interview

  • "Largest-first works because this currency is canonical, not because greedy is always right."
  • "I can check canonicity with a DP up to the sum of the two largest coins."
  • "For arbitrary coins I'd use the O(amount x coins) DP."
  • "With limited notes I'd keep the flexible ones, or search."

Practice

This skill comes with 9 multiple-choice questions that tell you which misconception a wrong answer reveals and 2 graded problems. Your answers are graded and your mastery is tracked, so you'll know when the skill holds up. Running code and saving progress need a free account.

Practice Greedy Denomination Coins free

Minimum Coins to Make Sum

EasyFreeCoding problemJava · Python

A cash drawer holds euros - the 1 and 2 euro coins and the 5 to 200 euro notes, so the values {1, 2, 5, 10, 20, 50, 100, 200} - as many of each as you need. Return the fewest pieces that add up to exactly amount.

Lemonade Change

EasyFreeCoding problemJava · Python

A lemonade stand charges $5 a cup. Customers come one at a time, each paying with a single $5, $10 or $20 bill. The stand starts with no cash and has to hand back exact change from the bills it has collected so far. Return whether every customer gets their change.

Practice Greedy Denomination Coins free

No card needed. Lessons, practice questions and easy problems are free forever.

Free plan, no card · 7-day Pro trial · Cancel anytime