Introduction to Greedy Algorithms

This lesson defines the greedy paradigm, explains the greedy choice property and optimal substructure, contrasts greedy with dynamic programming and divide-and-conquer, shows when greedy succeeds or fails, and maps classic greedy problems to real-world applications.

What is a Greedy Algorithm?

A greedy algorithm builds a solution step by step. At each step it makes the choice that looks best right now (locally optimal), without reconsidering past decisions. If the problem has the right structure, those local choices combine into a globally optimal solution.

Greedy is not a single formula—it is a design paradigm. You sort or scan inputs, pick the best eligible option at each stage, and often prove that skipping alternatives cannot improve the final answer.

Schematic: Activity selection

Pick the activity that finishes earliest; repeat on what remains compatible:

Activities (start, finish):
  A: (1,4)  B: (3,5)  C: (0,6)  D: (5,7)  E: (8,9)

Sort by finish time → A(1,4), B(3,5), D(5,7), E(8,9), C(0,6)
Greedy pick: A → skip B (overlap) → D → E
Result: {A, D, E} — maximum non-overlapping set

Greedy Choice Property & Optimal Substructure

A problem is a strong greedy candidate when both properties hold:

1. Greedy Choice Property

A globally optimal solution can be reached by making a locally optimal (greedy) choice first, then solving the reduced subproblem.

Example: In activity selection, some activity with the earliest finish time belongs to an optimal schedule—you can safely take it first.

2. Optimal Substructure

After the greedy choice, the remaining subproblem must also admit an optimal solution (same as in DP).

Example: After picking activity A, the best schedule for remaining time slots is an optimal solution to the smaller set of compatible activities.

Note: Optimal substructure alone is not enough—many DP problems have it but need exploring multiple choices. Greedy additionally requires that one local choice is always safe.

Greedy vs DP vs Divide-and-Conquer

All three decompose problems, but commitments and storage differ:

Approach Idea Stores sub-answers? Typical signal
Divide & Conquer Split into independent parts, combine Usually no table Merge sort, closest pair of points
Greedy One locally best irreversible choice per step Often O(1) extra Sort + pick; proof that greedy choice is safe
Dynamic Programming Compare multiple choices; cache overlapping states Table or memo map 0/1 knapsack, general coin change, LCS

Quick Comparison Examples

Greedy works — US coin change:

Amount: 30 cents, coins: [25, 10, 5, 1]
→ Take 25, then 5 → 2 coins ✓ (greedy optimal)

Greedy fails — arbitrary coin change:

Amount: 6, coins: [1, 3, 4]
Greedy: 4 + 1 + 1 = 3 coins
Optimal: 3 + 3 = 2 coins → need DP

Greedy works — fractional knapsack:

Items (weight, value): (10,60), (20,100), (30,120)
Value/weight: 6, 5, 4 → take highest ratio first, fractionally
Greedy gives maximum value for fractional items

When Greedy Works (and When It Fails)

Greedy is a good fit when
  • You can prove the greedy choice is always safe
  • Sorting by a key (ratio, deadline, finish time) drives decisions
  • Problem asks for max/min with matroid-like independence
  • Fractional versions allow taking parts of items
Switch to DP / other methods when
  • 0/1 choices block future options (0/1 knapsack)
  • Coin systems are non-canonical
  • Multiple competing local optima must be compared
  • No exchange argument or matroid proof is available

Common Proof Techniques

  • Exchange argument: Show any optimal solution can be transformed to include the greedy choice without worsening the answer.
  • Staying ahead: Prove greedy is never worse than any other strategy at each step.
  • Matroid theory: Independence systems where greedy on sorted weights is optimal (e.g., minimum spanning tree).
Interview trap: A greedy-looking loop is not enough—state why the first greedy pick cannot exclude an optimal solution. If you cannot argue it, try DP.

Classic Greedy Problems

These map to the tutorials in this greedy track:

1. Scheduling & Intervals

2. Resource & Encoding

3. Coin & Change

Other Famous Greedy Problems (reference)

  • Minimum spanning tree (Kruskal, Prim)
  • Dijkstra's shortest path (non-negative weights)
  • Interval partitioning, gas station, jump game II

Real-Life Applications

Greedy methods appear wherever local best choices compose into good global plans:

Greedy family Real-world use Example
Activity / schedulingMeeting rooms, CPU time slots, broadcast adsPack most non-overlapping meetings in a day
Fractional knapsackCargo loading, cloud budget splitsFill truck by value-per-kg ratio
Huffman codingFile compression (ZIP, JPEG stages), streamingShorter codes for frequent symbols
Job sequencingManufacturing batches, ad campaign slotsMax profit jobs before deadlines
Coin change (greedy)POS change, fare machinesUS coins: quarters first
MST / routingNetwork design, pipeline layoutConnect cities with minimum cable
DijkstraGPS navigation, game pathfindingShortest route on road networks

Cross-Domain Examples

  • Networking: Kruskal/Prim for minimum-cost backbone links
  • Finance: Greedy heuristics for portfolio rebalancing under constraints
  • Compression: Huffman trees in DEFLATE and media codecs
  • Operations: Job shop scheduling with deadline-driven ordering
  • Education: Canonical coin systems teach why greedy proofs matter
Learn the pattern, not just the puzzle: Recognizing “sort by finish time” or “sort by value/weight ratio” lets you reuse the same proof skeleton across interview problems.

Key Takeaway

Greedy = locally optimal choice + proof it is safe + often sort first.

Steps to Solve Greedy Problems

  1. Identify the greedy criterion — What should be maximized/minimized at each step? (ratio, finish time, deadline)
  2. Sort or prioritize — Order inputs so the best local choice is at the front.
  3. Make irreversible choices — Pick the best feasible option; discard incompatible items.
  4. Prove correctness — Exchange argument or greedy-choice lemma (interviews).
  5. Implement & analyze — Usually O(n log n) from sorting; O(n) scan after sort.
  6. Test counterexamples — Try small cases where greedy might fail; if it fails, use DP.

Next Steps

Continue Learning

  1. Activity Selection — Classic interval scheduling with proof
  2. Fractional Knapsack — Value/weight ratio greedy
  3. Huffman Coding — Build optimal prefix codes
  4. Dynamic Programming Intro — When greedy is not enough

Practice Problems

Beginner Level:

Intermediate Level:

Summary

Concept Key Points
DefinitionBuild solution by repeated locally optimal choices
PropertiesGreedy choice property + optimal substructure
Versus DPGreedy commits; DP compares and stores alternatives
Typical complexityO(n log n) sort + O(n) scan
Proof toolsExchange argument, staying ahead, matroids
GoalSimple, fast algorithms when greedy is provably optimal

Quick Reference Card

When to try greedy:

  • ✓ Sorting by time, ratio, or deadline suggests itself
  • ✓ Fractional or interval-style problems
  • ✓ MST, Dijkstra, Huffman patterns
  • ✓ You can articulate an exchange argument

When to avoid greedy:

  • ✗ 0/1 knapsack (use DP)
  • ✗ General coin change (use DP)
  • ✗ Need to count ways or try many combinations

Compare with: Dynamic Programming for overlapping subproblems and multi-choice decisions.