Greedy Algorithms
At each step, make the locally optimal choice and never look back. No exhaustive search, no memoization. Provably correct when the greedy choice property holds — swapping a greedy choice for any other can't improve the result.
DP explores every possibility. Greedy makes one irrevocable choice per step and never looks back — and provably gets the optimal answer.
Greedy works when the problem has the greedy choice property: choosing the locally best option at each step leads to a globally optimal solution. Prove it with the exchange argument — assume an optimal solution doesn't include your greedy choice, then show swapping your choice in doesn't make things worse.
The Exchange Argument
The proof template — almost every greedy problem uses this.
Suppose there is an optimal solution OPT that differs from greedy solution G at some step. Greedy chose X; OPT chose Y (where X ≠ Y). Show that swapping Y for X in OPT produces a solution that is at least as good as OPT. This means X is safe to choose — the greedy step never loses.
The 3-Step Framework
Sort → scan → decide — 95% of greedy problems follow this shape.
What ordering makes local choices lead to global optimum? For intervals: sort by end time (leaves max room). For frequency problems: sort by count descending. For string construction: process digits/chars in value order. The sort is almost always the key insight.
# Intervals: sort by end
pairs.sort(key=lambda x: x[1])
# Frequency: Counter + sorted keys
for d in '9876543210': ...
# Stack greedy: last occurrence map
last = {ch: i for i, ch in enumerate(s)}Scan the sorted input. At each element, make the locally optimal decision using only the current state (last selected end, current open counter, stack top, etc.). Never re-examine a past choice. The state is minimal — usually one or two variables.
# Interval greedy: one variable tracks frontier
if start > last_end:
count += 1
last_end = end
# Parentheses: two counters
if ch=='(': open += 1
elif open > 0: open -= 1
else: close += 1For interviews: either know the exchange argument for your specific problem, or recognize a known greedy pattern (interval scheduling, Huffman, Dijkstra, Kruskal). You don't need a formal proof — just explain why a non-greedy choice can't do better.
# Known greedy patterns: # Interval scheduling → sort by end time # Connect ropes / Huffman → min-heap (always cheapest pair) # Jump Game → track max reachable position # Gas Station → circular greedy with deficit tracking # Coin change (canonical coins) → largest coin first
Pattern Recognition
'Maximum selection', 'minimum cost', 'locally optimal choice' = greedy candidate.