Greedy Local Optimum โ Global Optimum
Make the best choice at each step. Never go back. If local decisions lead to a global optimum, greedy gives the simplest and fastest solution โ often O(n log n) or O(n). The challenge isn't coding; it's proving correctness.
What is Greedy?
A greedy algorithm makes the locally optimal choice at each step and never revises it. It works when the problem has the "greedy choice property" โ a locally optimal choice leads to a globally optimal solution. Unlike dynamic programming (which considers all subproblems before choosing), greedy commits immediately. Unlike backtracking (which explores and undoes), greedy never undoes. This makes greedy algorithms simple to code and fast to run (typically O(n log n) for the sort step + O(n) for the greedy scan). The hard part is correctness โ proving that greedy works for a given problem. In interviews, the "exchange argument" suffices: show that swapping any non-greedy choice for the greedy choice never makes things worse.
How It Thinks
When Greedy Works (and When It Doesn't)
| Aspect | Greedy | Dynamic Programming |
|---|---|---|
| Decision | Commit immediately, never revise | Consider all subproblems, pick best |
| Correctness | Exchange argument (harder to prove) | Optimal substructure (systematic) |
| Time | O(n log n) or O(n) typically | O(nยฒ) or more typically |
| When it works | Local optimum = global optimum | Overlapping subproblems + optimal substructure |
| Coin change {1,5,10,25} | โ Greedy works (standard denom) | Also works (but slower) |
| Coin change {1,3,4} โ 6 | โ Greedy: 4+1+1=3 coins | โ DP: 3+3=2 coins |
- Try greedy first โ it's faster and simpler. Test it with a small counterexample.
- If the greedy answer matches the optimal answer for all small cases you can think of, code it.
- If you find a counterexample, switch to DP.
- Many interviewers accept: "I suspect greedy works here because [exchange argument]. Let me verify with an example."
Interval Scheduling โ The Classic Greedy
The interval scheduling maximisation problem: given n intervals, select the maximum number of non-overlapping intervals. The greedy strategy: sort by END time, greedily pick the earliest-ending interval that doesn't overlap with the last picked. This always works because picking the earliest-ending interval leaves the most room for future intervals (exchange argument).
Max Non-Overlapping
Pick earliest-ending. Skip if start < last end. Greedy picks: most activities, minimum removals.
Merge Overlapping
Merge if current start โค prev end. Extend prev end. Use for Merge Intervals (LC 56).
Jump Game โ Reachability Greedy
- Each "level" is the range of indices reachable with the current number of jumps.
curEnd= level boundary. farthest= how far the next level reaches. Increment jumps when you pass a level boundary.
Common Greedy Patterns
| Pattern | Strategy | Example |
|---|---|---|
| Sort by end time | Pick earliest-ending, skip overlapping | Non-overlapping Intervals (LC 435) |
| Track farthest | At each index, update farthest reachable | Jump Game I & II (LC 55, 45) |
| Sort + heap | Sort by one criterion, heap tracks other | Meeting Rooms II (LC 253) |
| Balance + / โ | Track running surplus, find start position | Gas Station (LC 134) |
| Greedy from both ends | Process from left and right, merge | Candy (LC 135) |
| Digit greedy | Build largest/smallest number digit-by-digit | Remove K Digits (LC 402) |
Recognising Greedy Problems
| Signal | Greedy Strategy | Example |
|---|---|---|
| "maximum non-overlapping intervals" | Sort by end time, pick greedily | Non-overlapping Intervals (LC 435) |
| "minimum meeting rooms" | Sort by start, min-heap of end times | Meeting Rooms II (LC 253) |
| "can you reach the end" / "minimum jumps" | Track farthest reachable index | Jump Game I & II (LC 55, 45) |
| "gas station circuit" / "running surplus" | Track tank, reset when negative | Gas Station (LC 134) |
| "assign cookies" / "match capacity to demand" | Sort both, match smallest viable | Assign Cookies (LC 455) |
| "remove K digits for smallest number" | Monotonic stack, remove peaks | Remove K Digits (LC 402) |
Build It Once
Build three greedy patterns: interval scheduling, jump game, and gas station. These cover the main families. Every other greedy problem is "sort + scan + simple state."
Use It In Java
| Idiom | Code | When |
|---|---|---|
| Sort by end time | Arrays.sort(iv, (a,b) -> a[1] - b[1]); | Interval scheduling / removals |
| Sort by start time | Arrays.sort(iv, (a,b) -> a[0] - b[0]); | Merge intervals / meeting rooms |
| Track farthest | farthest = Math.max(farthest, i + nums[i]); | Jump game / reachability |
| Running surplus + reset | if (tank < 0) { start = i+1; tank = 0; } | Gas station / circular problems |
| Two-pass (LโR, RโL) | Left pass + right pass with Math.max | Candy / trapping rain water |
| Min-heap for "smallest available" | PriorityQueue<Integer> pq = new PriorityQueue<>(); | Meeting rooms, task scheduler |
int[][] intervals, (a,b) -> a[1] - b[1] can overflow if values are near Integer.MAX_VALUE. Use Integer.compare(a[1], b[1]) for safety. In interviews, the subtraction form is fine for typical inputs.
Problems To Solve
Greedy problems tend to be "aha" problems โ the solution is simple once you see it, but hard to discover. Focus on understanding WHY greedy works (exchange argument) and learning to recognise the pattern (sort + scan). If you can't explain why greedy is correct, switch to DP.
| Difficulty | Pattern | Problem | Key Insight |
|---|---|---|---|
| Medium | reachability | Jump Game โ LC 55 | Track farthest reachable. If i > farthest โ unreachable. O(n). |
| Medium | BFS-greedy | Jump Game II โ LC 45 | BFS levels: track current range end and farthest. Increment jumps at level boundary. O(n). |
| Medium | intervals | Non-overlapping Intervals โ LC 435 | Sort by end. Greedily keep earliest-ending. Remove count = total โ kept. |
| Medium | intervals | Merge Intervals โ LC 56 | Sort by start. Merge if current start โค prev end. |
| Medium | surplus | Gas Station โ LC 134 | Total gas โฅ total cost โ solution exists. Track running tank; reset on negative. |
| Hard | two-pass | Candy โ LC 135 | Two-pass greedy: left-to-right ensures higher-rating-than-left gets more; right-to-left ensures higher-than-right; take max. |
- See "interval scheduling / overlap" โ sort by end, sweep. See "can you reach / minimum jumps" โ track farthest.
- See "circular surplus" โ running sum, reset on negative.
- Greedy is always: sort (optional) โ single pass โ a few variables.
- If you need a dp table or memoisation โ it's not greedy.