Lesson 23 of 30
A strategy that always takes the best-looking choice at each step, without looking ahead — fast and often right, but honestly not always right, and it's worth knowing why.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
This topic is about judgment and practical tradeoffs more than a single right answer — a mock interview is the better way to test yourself on it.
Be interviewed on this →Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
Imagine you're making change and want to hand back the fewest coins possible. A natural strategy: grab the biggest coin that still fits, then repeat with what's left. Need to make 41 cents? Grab a quarter, then a dime, then a nickel, then a penny. Done — four coins, no calculator needed.
That instinct — always take the best-looking option right now, and never look back — is a greedy algorithm. It doesn't plan ahead. It doesn't reconsider an earlier choice. It grabs whatever looks best at this exact moment and moves on.
Greedy algorithms are appealing because they're fast and easy to reason about. But here's the part that matters more: greedy isn't always right. Grabbing the best option right now can sometimes lead you somewhere worse overall, because a less obvious choice earlier would have opened up a better path later.
That might feel unsettling — an algorithm that's usually right but not always? It is. That's exactly why recognizing "is this a situation where greedy is safe?" is its own skill, not a formality you can skip.
// Greedy: always grab the biggest coin that still fits.
function greedyChange(amount, coins) {
const sorted = [...coins].sort((a, b) => b - a); // biggest coin first
const used = [];
for (const coin of sorted) {
while (amount >= coin) {
amount -= coin;
used.push(coin);
}
}
return used;
}
console.log(greedyChange(41, [25, 10, 5, 1])); // [25, 10, 5, 1] — correct, 4 coins
// With a different, unusual set of coins, greedy can go wrong:
console.log(greedyChange(8, [1, 4, 5])); // [5, 1, 1, 1] — 4 coins
// The best possible answer is actually [4, 4] — only 2 coins.
// Greedy grabbed 5 first because it looked best in the moment,
// and that early choice boxed it into a worse total.
This sits right next to dynamic programming, from the previous lesson. Both make a sequence of choices, but dynamic programming double-checks itself by remembering alternatives, while greedy commits immediately and never looks back. Comparing the two side by side is often the fastest way to tell which a problem actually needs.