Skip to content

Intermediate: core algorithms · Heaps and greedy algorithms · topic 38 of 61 · 35 min

Greedy algorithms: the idea

Explanation

A greedy algorithm builds an answer step by step and, at each step, takes the choice that looks best right now, never going back. It is fast and simple, but it is only correct when the problem has the greedy-choice property. You show that with an exchange argument. Picking the most meetings for one room (sort by end time) and giving change with Indian notes and coins are classic cases where greedy works; the coin system {1, 3, 4} shows where it fails.

What "greedy" means

A greedy algorithm makes one choice at a time, always taking the option that looks best at that moment (the most valuable, the cheapest, the earliest to finish), and never undoes a choice. Because it never looks back, it is usually just a sort plus one pass: O(n log n) time.

The catch: a locally best step does not always lead to the best overall answer. So with greedy there are always two questions: what is the greedy rule, and why is it correct? In interviews, giving a short reason, or a counterexample for a wrong rule, matters as much as the code.

When greedy works

  • Greedy-choice property: there is always an optimal answer that includes the greedy first choice. So taking it never hurts.
  • Optimal substructure: after the greedy choice, what is left is a smaller problem of the same kind, and an optimal answer to it, plus the first choice, is optimal overall.

The usual way to argue the first point is an exchange argument. Take ANY optimal answer. If it does not use the greedy choice, swap one of its choices for the greedy one and show the answer is still valid and no worse. Then an optimal answer with the greedy choice exists.

Example 1: the most meetings in one room

A single meeting room gets requests (start, end). Choose the largest number of meetings that do not overlap; a meeting may start exactly when the previous one ends. This is the activity selection problem. The greedy rule: sort by END time, and take each meeting that starts at or after the end of the last one taken.

python
def max_meetings(meetings):
    count, last_end = 0, float("-inf")
    for start, end in sorted(meetings, key=lambda m: m[1]):
        if start >= last_end:
            count += 1
            last_end = end
    return count

print(max_meetings([(1, 4), (3, 5), (0, 6), (5, 7), (8, 9), (5, 9)]))   # Output: 3
It picks (1, 4), (5, 7) and (8, 9). Sorting is O(n log n); the pass is O(n).

Why the earliest end? Exchange argument: let the meeting that ends first be g. Any optimal schedule has some first meeting f. Since g ends no later than f, replace f with g: g still ends before the second meeting starts, so nothing overlaps and the count is the same. Taking g is therefore safe, and the rest is the same problem on the meetings that start after g ends.

Other rules that sound sensible are wrong. "Earliest start first" can pick one long meeting (0, 10) and block (1, 2), (3, 4) and (5, 6). "Shortest first" picks (4, 7) from (1, 5), (4, 7), (6, 10) and blocks both others, which fit together.

Example 2: change with Indian notes and coins

To pay an amount with the fewest notes and coins of ₹1, 2, 5, 10, 20, 50, 100, 200 and 500, take the largest denomination that fits, again and again. ₹1,388 becomes 500 + 500 + 200 + 100 + 50 + 20 + 10 + 5 + 2 + 1: ten pieces. For this set the greedy answer is always the minimum, because each denomination relates well to the smaller ones (systems like this are called canonical). ATMs and cash counters follow the same idea, limited by what notes they hold.

python
NOTES = [500, 200, 100, 50, 20, 10, 5, 2, 1]

def make_change(amount):
    used = []
    for note in NOTES:
        while amount >= note:
            amount -= note
            used.append(note)
    return used

print(make_change(1388))   # Output: [500, 500, 200, 100, 50, 20, 10, 5, 2, 1]

Where greedy fails: coins {1, 3, 4}

Now use coins of 1, 3 and 4 to make 6. Greedy takes 4, then 1, then 1: three coins. The best answer is 3 + 3: two coins. Taking the biggest coin first was a trap. With coins {5, 10} and amount 3, greedy gets stuck, and so does every method, because 3 cannot be made at all. For coin systems that are not canonical you need dynamic programming (Module 11), which tries every last coin and builds up answers for all smaller amounts.

Tip: Before trusting a greedy rule, try to break it with a tiny example of 2 to 4 items. If you cannot find a counterexample, write the exchange argument in one or two sentences.

Common mistakes

  • Using greedy because it "feels right" without a reason. Fix: give an exchange argument or test small cases against brute force.
  • Sorting meetings by start time or by length. Fix: sort by end time for maximum non-overlapping meetings.
  • Getting the touching rule wrong: if back-to-back meetings are allowed, use start >= last_end; if not, use start > last_end. Ask.
  • Assuming greedy change works for any coin system. Fix: it is correct for systems like Indian or US currency, not for {1, 3, 4}; use DP otherwise.
  • Forgetting to sort a copy when the caller still needs the original order. Fix: sorted(items, key=...) returns a new list.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Greedy algorithms: the idea · 1/8

Greedy algorithms

This lesson explains greedy algorithms: take the best choice now and never look back.

Prefer a video by a teacher? Find free videos on “greedy algorithm activity selection exchange argument coin change greedy fails” on YouTube ↗

In real life: Booking a shared conference room

An office has one board room and receives booking requests for tomorrow. The admin wants to approve as many meetings as possible. Sorting by end time and approving each request that starts after the last approved one ends gives the maximum number of meetings, and the exchange argument shows no other choice can do better. Payroll teams that pay salaries in cash use the greedy note count to plan how many notes of each kind to draw from the bank.

python
requests = [("Sales", 9, 11), ("HR", 10, 12), ("Tech", 11, 12), ("Design", 12, 13), ("Ops", 9, 13)]
approved, last_end = [], 0
for team, start, end in sorted(requests, key=lambda r: r[2]):
    if start >= last_end:
        approved.append(team)
        last_end = end
print(approved)
Shows ['Sales', 'Tech', 'Design']: three meetings, back to back from 9 to 13.

Practice (0/3 done)

Task 1 · Code · Python

Write min_notes_greedy(amount) that returns how many notes and coins are needed to pay amount (an integer ≥ 0) using the Indian denominations 500, 200, 100, 50, 20, 10, 5, 2 and 1, taking the largest that fits each time. Example: min_notes_greedy(1388) returns 10.

Task 2 · Code · Python

Write max_meetings(meetings) where meetings is a list of (start, end) with start < end. Return the largest number of meetings one room can hold with no overlap. A meeting MAY start exactly when the previous one ends. Use the greedy rule: sort by end time. Example: max_meetings([(1, 4), (3, 5), (0, 6), (5, 7), (8, 9), (5, 9)]) returns 3.

Task 3 · Code · Python

Write greedy_vs_optimal(coins, amount). coins is a list of distinct positive integers in any order; amount ≥ 0. Return a tuple (greedy_count, optimal_count). greedy_count: repeatedly take the largest coin that fits; if you get stuck with something left, it is -1. optimal_count: the true minimum number of coins (use a small dynamic programming table over 0..amount); -1 if the amount cannot be made. Example: greedy_vs_optimal([1, 3, 4], 6) returns (3, 2).

Quick quiz

Question 1

1.What does a greedy algorithm do at each step?

Question 2

2.For the most non-overlapping meetings in one room, sort by…

Question 3

3.Coins {1, 3, 4} and amount 6: how many coins do greedy and the best answer use?

Question 4

4.What does an exchange argument show?

Question 5

5.Meetings (1, 5), (4, 7), (6, 10). What does "shortest meeting first" pick, and what is the best?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

What does a greedy algorithm do at each step?

Answer: Takes the choice that looks best now and never undoes it

Greedy commits to the locally best choice. Trying everything is brute force; storing sub-answers is dynamic programming.

For the most non-overlapping meetings in one room, sort by…

Answer: end time

The meeting that ends first leaves the most room for the rest; the exchange argument proves it.

Coins {1, 3, 4} and amount 6: how many coins do greedy and the best answer use?

Answer: Greedy 3, best 2

Greedy takes 4 + 1 + 1. The best is 3 + 3.

What does an exchange argument show?

Answer: That swapping a choice in any optimal answer for the greedy choice keeps it valid and no worse

So an optimal answer containing the greedy choice exists, and taking it is safe.

Meetings (1, 5), (4, 7), (6, 10). What does "shortest meeting first" pick, and what is the best?

Answer: It picks 1, the best is 2

Shortest is (4, 7), which overlaps both others. Taking (1, 5) and (6, 10) gives 2.

Coins [1, 3, 4], amount 6. What does "always take the largest coin that fits" give, and what is optimal?Related

Answer: 3 coins and 2 coins

Greedy takes 4, 1, 1 (three coins); 3 + 3 needs only two. That is why DP is needed.

From 1-D DP classics

In the minimum meeting rooms solution, what does the min-heap store?Related

Answer: End times of meetings currently using a room

The root is the room that frees up first; if it is free by the next start, that room is reused.

From Interval problems

Why does the fractional knapsack greedy fail on the 0/1 knapsack?Related

Answer: Because whole items can leave unused space, so the best value per kilo is not always best overall

With capacity 50, greedy takes 60 + 100 = 160 and cannot fit the 30 kg item; 100 + 120 = 220 is better.

From More greedy classics

Which is a good way to start a meeting?Related

Answer: Shall we get started?

"Shall we get started?" is a friendly, natural way to begin.

From Meetings and video calls

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 2 more topics in “Heaps and greedy algorithms” before its exam: Interval problems, More greedy classics.
  2. Module 8 exam: Heaps and greedy algorithms · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Graphs. 61 topics left in the course before the final exam.

← Previous: Heap patterns: top-k and streams