Algorithms

Greedy Algorithms

πŸ“‹ At a Glance

AspectDetails
Time to Read35 minutes
PrerequisitesPart 1 (Algorithm Analysis), Part 16 (DP basics)
Key ConceptsGreedy Choice, Activity Selection, Huffman, Scheduling
Difficulty⭐⭐⭐ (Intermediate)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    GREEDY ALGORITHMS                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  THE GREEDY APPROACH                                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚                                                         β”‚    β”‚
β”‚  β”‚  At each step, make the locally optimal choice          β”‚    β”‚
β”‚  β”‚  Hope it leads to globally optimal solution             β”‚    β”‚
β”‚  β”‚                                                         β”‚    β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”               β”‚    β”‚
β”‚  β”‚  β”‚Start│───→│Best │───→│Best │───→│Goal β”‚               β”‚    β”‚
β”‚  β”‚  β”‚     β”‚    β”‚localβ”‚    β”‚localβ”‚    β”‚     β”‚               β”‚    β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”˜               β”‚    β”‚
β”‚  β”‚                                                         β”‚    β”‚
β”‚  β”‚Works when: Greedy choice property + Optimal substructureβ”‚    β”‚
β”‚  β”‚                                                         β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                 β”‚
β”‚  CLASSIC PROBLEMS                                               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚  β”‚ Activity Select β”‚  β”‚ Huffman Coding  β”‚                       β”‚
β”‚  β”‚ ─────────────── β”‚  β”‚ ─────────────── β”‚                       β”‚
β”‚  β”‚ Max activities  β”‚  β”‚ Optimal prefix  β”‚                       β”‚
β”‚  β”‚ without overlap β”‚  β”‚ codes           β”‚                       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                       β”‚
β”‚  β”‚ Fractional      β”‚  β”‚ Job Scheduling  β”‚                       β”‚
β”‚  β”‚ Knapsack        β”‚  β”‚ ─────────────── β”‚                       β”‚
β”‚  β”‚ ─────────────── β”‚  β”‚ Minimize        β”‚                       β”‚
β”‚  β”‚ Max value with  β”‚  β”‚ penalties       β”‚                       β”‚
β”‚  β”‚ fractions       β”‚  β”‚                 β”‚                       β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                       β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 What You'll Learn

After completing this article, you will be able to:

  1. Identify greedy problems: Recognize when greedy works
  2. Prove correctness: Exchange argument and greedy stays ahead
  3. Solve classic problems: Activity selection, Huffman, scheduling
  4. Avoid pitfalls: Know when greedy fails

πŸ”₯ Production Story: The Task Scheduler Optimization

A cloud platform needed to schedule thousands of tasks to minimize total completion time.

The Problem

JAVA(10 lines)
Code
Loading syntax highlighter...

The Solution: Shortest Job First

JAVA(30 lines)
Code
Loading syntax highlighter...

Why It Works (Exchange Argument)

If tasks aren't in SJF order, we can improve by swapping adjacent jobs:

Before swap: [..., A, B, ...]  where duration(A) > duration(B)
            A completes at time t
            B completes at time t + duration(B)

After swap:  [..., B, A, ...]
            B completes at time t - duration(A) + duration(B) = t'
            A completes at time t

Since duration(B) < duration(A):
- B's completion time decreased
- A's completion time stayed same
- Total improved!

Therefore, SJF order is optimal.

🧠 Mental Model: The Greedy Framework

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                 GREEDY ALGORITHM FRAMEWORK                      β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  STEP 1: Identify the greedy choice                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚ What's the "best" item to pick first?                   β”‚    β”‚
β”‚  β”‚ - Largest? Smallest? Earliest finish? Best ratio?       β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                 β”‚
β”‚  STEP 2: Prove greedy choice is safe                            β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚ Show: There exists an optimal solution that includes    β”‚    β”‚
β”‚  β”‚       our greedy choice                                 β”‚    β”‚
β”‚  β”‚                                                         β”‚    β”‚
β”‚  β”‚ Methods:                                                β”‚    β”‚
β”‚  β”‚ - Exchange argument                                     β”‚    β”‚
β”‚  β”‚ - Greedy stays ahead                                    β”‚    β”‚
β”‚  β”‚ - Structural argument                                   β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                 β”‚
β”‚  STEP 3: Prove optimal substructure                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”‚
β”‚  β”‚ After making greedy choice, remaining problem is        β”‚    β”‚
β”‚  β”‚ smaller instance of same problem                        β”‚    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”¬ Deep Dive: Activity Selection

The Problem

Given activities with start and end times, select maximum non-overlapping activities.

JAVA(18 lines)
Code
Loading syntax highlighter...

Why Earliest Finish First Works

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚            ACTIVITY SELECTION PROOF                             β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Claim: Greedy choice (earliest finish) is always safe          β”‚
β”‚                                                                 β”‚
β”‚  Proof by exchange:                                             β”‚
β”‚  Let OPT be any optimal solution                                β”‚
β”‚  Let a₁ be the activity with earliest finish time               β”‚
β”‚  Let a_first be the first activity in OPT                       β”‚
β”‚                                                                 β”‚
β”‚  If a₁ = a_first: Done! Greedy matches OPT                      β”‚
β”‚                                                                 β”‚
β”‚  If a₁ β‰  a_first:                                               β”‚
β”‚    - a₁ finishes no later than a_first (earliest finish)        β”‚
β”‚    - Replace a_first with a₁ in OPT                             β”‚
β”‚    - No new conflicts (a₁ ends earlier)                         β”‚
β”‚    - Same size, still valid β†’ OPT' is optimal with a₁           β”‚
β”‚                                                                 β”‚
β”‚  Timeline:                                                      β”‚
β”‚  a₁:     |-----|                                                β”‚
β”‚  a_first:|--------|                                             β”‚
β”‚  next:            |-----|                                       β”‚
β”‚                                                                 β”‚
β”‚  Swapping a_first β†’ a₁ can only add more room for next          β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Weighted Activity Selection

When activities have weights, greedy doesn't work - need DP:

JAVA(35 lines)
Code
Loading syntax highlighter...

πŸ”¬ Deep Dive: Huffman Coding

The Problem

Create optimal prefix-free codes for data compression.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    HUFFMAN CODING                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  Characters: a(45%), b(13%), c(12%), d(16%), e(9%), f(5%)       β”‚
β”‚                                                                 β”‚
β”‚  Fixed-length: 3 bits each β†’ 3 Γ— 100 = 300 bits                 β”‚
β”‚                                                                 β”‚
β”‚  Huffman tree:                                                  β”‚
β”‚              (100)                                              β”‚
β”‚             /     \                                             β”‚
β”‚          (55)     a(45)                                         β”‚
β”‚         /    \       0                                          β”‚
β”‚      (25)    (30)                                               β”‚
β”‚      /  \    /  \                                               β”‚
β”‚    c(12) b(13) d(16) (14)                                       β”‚
β”‚     100   101   110  /  \                                       β”‚
β”‚                    f(5) e(9)                                    β”‚
β”‚                    1110  1111                                   β”‚
β”‚                                                                 β”‚
β”‚  Huffman: 1Γ—45 + 3Γ—13 + 3Γ—12 + 3Γ—16 + 4Γ—9 + 4Γ—5 = 224 bits      β”‚
β”‚  Savings: 25%                                                   β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Implementation

JAVA(87 lines)
Code
Loading syntax highlighter...

Why Huffman is Optimal

Greedy choice: Always merge two nodes with smallest frequencies

Proof idea:
1. Optimal tree exists where two lowest-frequency symbols are siblings
   at the deepest level (exchange argument)

2. After merging, we have smaller instance of same problem
   (one fewer symbol, combined frequency)

3. Recursively optimal β†’ globally optimal

πŸ”¬ Deep Dive: Fractional Knapsack

The Problem

Unlike 0/1 knapsack, we can take fractions of items.

JAVA(36 lines)
Code
Loading syntax highlighter...

Comparison with 0/1 Knapsack

Items: weights = [10, 20, 30], values = [60, 100, 120], capacity = 50

Ratios: 60/10=6, 100/20=5, 120/30=4

Fractional (greedy):
- Take all of item 1: value=60, remaining=40
- Take all of item 2: value=60+100=160, remaining=20
- Take 20/30 of item 3: value=160+120Γ—(20/30)=240

0/1 (DP needed):
- Take items 2 and 3: value=100+120=220

Greedy gives 240 for fractional, but would give wrong answer for 0/1!

πŸ”¬ Deep Dive: Job Scheduling

Minimizing Lateness

JAVA(24 lines)
Code
Loading syntax highlighter...

Job Scheduling with Profits and Deadlines

JAVA(71 lines)
Code
Loading syntax highlighter...

πŸ”¬ Deep Dive: When Greedy Fails

Coin Change Problem

JAVA(19 lines)
Code
Loading syntax highlighter...

The Key Difference

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           GREEDY vs DYNAMIC PROGRAMMING                         β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                                 β”‚
β”‚  GREEDY                                                         β”‚
β”‚  ───────                                                        β”‚
β”‚  - Makes one choice at each step                                β”‚
β”‚  - Never reconsiders choices                                    β”‚
β”‚  - Works when: greedy choice property holds                     β”‚
β”‚  - Time: Usually O(n) or O(n log n)                             β”‚
β”‚                                                                 β”‚
β”‚  DYNAMIC PROGRAMMING                                            β”‚
β”‚  ────────────────────                                           β”‚
β”‚  - Considers all choices at each step                           β”‚
β”‚  - Stores results for future use                                β”‚
β”‚  - Works when: optimal substructure only                        β”‚
β”‚  - Time: Usually O(nΒ²) or O(nΓ—k)                                β”‚
β”‚                                                                 β”‚
β”‚  Rule of thumb:                                                 β”‚
β”‚  ───────────────                                                β”‚
β”‚  1. Try greedy first (simpler, faster)                          β”‚
β”‚  2. Find counterexample β†’ use DP                                β”‚
β”‚  3. Prove greedy works β†’ keep greedy                            β”‚
β”‚                                                                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

⚠️ Common Mistakes

Mistake 1: Assuming Greedy Always Works

JAVA(10 lines)
Code
Loading syntax highlighter...

Mistake 2: Wrong Greedy Criterion

JAVA(5 lines)
Code
Loading syntax highlighter...

Mistake 3: Not Handling Ties Properly

JAVA(16 lines)
Code
Loading syntax highlighter...

πŸ› Debug This: Activity Selection Bug

This activity selection has a bug. Can you find it?

JAVA(16 lines)
Code
Loading syntax highlighter...
πŸ” Click to reveal the bug
Bug: Sorting by duration instead of end time.
JAVA(5 lines)
Code
Loading syntax highlighter...
Counterexample:
Activities: [0,10], [1,3], [3,5], [5,7], [7,9]

Shortest duration first: [1,3] (len 2), [3,5] (len 2), [5,7] (len 2), [7,9] (len 2), [0,10] (len 10)
Result: [1,3], [3,5], [5,7], [7,9] = 4 activities βœ“

But consider: [0,2], [1,10], [2,3]
Shortest first: [0,2] (len 2), [2,3] (len 1), [1,10] (len 9)
Order: [2,3], [0,2], [1,10]
Result: [2,3] (can't add [0,2] - overlaps!) = 1 activity

Earliest finish: [0,2], [2,3], [1,10]
Result: [0,2], [2,3] = 2 activities βœ“

πŸ’» Exercises

Exercise 1: Assign Mice to Holes ⭐⭐

N mice and N holes on a line. Find minimum time for all mice to reach holes (each mouse to one hole).

JAVA(3 lines)
Code
Loading syntax highlighter...

Exercise 2: Minimum Platforms ⭐⭐

Given arrival and departure times of trains, find minimum platforms needed.

JAVA(3 lines)
Code
Loading syntax highlighter...

Exercise 3: Gas Station ⭐⭐⭐

N gas stations in a circle. Find starting station to complete the circuit.

JAVA(3 lines)
Code
Loading syntax highlighter...

Exercise 4: Jump Game II ⭐⭐⭐

Minimum jumps to reach end. Each position has max jump length.

JAVA(3 lines)
Code
Loading syntax highlighter...

Exercise 5: Meeting Rooms III ⭐⭐⭐⭐

Given n rooms and meetings, find which room held most meetings. Meetings go to lowest numbered available room.

JAVA(3 lines)
Code
Loading syntax highlighter...

🎀 Interview Questions

Q1: "How do you prove a greedy algorithm is correct?"

Answer: Two main techniques:
1. Exchange Argument:
  • Take any optimal solution OPT
  • Show we can transform it to match greedy without worsening
  • Usually swap elements to show greedy choice is at least as good
2. Greedy Stays Ahead:
  • Define a measure of progress
  • Show greedy solution is always at least as good as any other
  • By induction: if greedy is ahead at step k, it stays ahead at step k+1
Example for Activity Selection:
Exchange: If OPT's first activity isn't earliest-finish,
          swap it with earliest-finish activity.
          Result: same or fewer conflicts.

Stays ahead: At each step, greedy has at least as many
             activities AND ends no later than any other
             solution with same number of activities.

Q2: "When should I try greedy vs DP?"

Answer:
Try Greedy First When:
  • Problem has "optimal substructure"
  • Local choices seem to lead to global optimum
  • You can identify a clear greedy criterion
Use DP When:
  • Greedy counterexample exists
  • Need to consider multiple choices
  • Problem has overlapping subproblems
Quick Test:
  1. Propose greedy strategy
  2. Try to find counterexample
  3. If found β†’ use DP
  4. If not β†’ try to prove greedy works

Q3: "Implement interval scheduling with weights."

Answer:
JAVA(30 lines)
Code
Loading syntax highlighter...

Key insight: Greedy doesn't work with weights. Need DP because taking an interval affects which others we can take.


Q4: "Design an algorithm for task scheduling with dependencies."

Answer: Use topological sort + greedy:
JAVA(32 lines)
Code
Loading syntax highlighter...

Q5: "What's the difference between Huffman and Shannon-Fano coding?"

Answer:
AspectHuffmanShannon-Fano
ApproachBottom-up (merge smallest)Top-down (split into halves)
OptimalityOptimal prefix codeNear-optimal
ConstructionBuild tree from leavesDivide symbols recursively
ComplexityO(n log n)O(n log n)
Huffman is always optimal for symbol-by-symbol coding because:
  1. Merging two smallest frequencies is provably safe
  2. Resulting tree has minimum weighted path length

Shannon-Fano can produce suboptimal codes because splitting by frequency doesn't guarantee optimal bit allocation.


πŸ“‹ Quick Reference

Classic Greedy Problems

ProblemGreedy CriterionTime
Activity SelectionEarliest finishO(n log n)
Huffman CodingSmallest frequenciesO(n log n)
Fractional KnapsackBest value/weightO(n log n)
Job Scheduling (lateness)Earliest deadlineO(n log n)
Minimum Spanning TreeSmallest edgeO(E log V)
Dijkstra's AlgorithmClosest vertexO((V+E) log V)

When Greedy Fails

ProblemWhy Greedy Fails
0/1 KnapsackCan't take fractions
Coin Change (general)Skipping a coin might be better
Longest PathLocal longest doesn't give global
Graph ColoringGreedy can use more colors

Proof Techniques

Exchange Argument:
1. Let OPT be optimal solution
2. If OPT differs from greedy at step k
3. Show we can swap to match greedy
4. Solution doesn't worsen β†’ greedy is optimal

Greedy Stays Ahead:
1. Define measure M (e.g., activities selected)
2. Show M(greedy, k) β‰₯ M(any other, k) for all k
3. By induction, greedy ends up optimal

πŸ”— What's Next?

In Part 20: Backtracking & Branch and Bound, we'll explore:
  • Backtracking template
  • N-Queens, Sudoku solver
  • Subset/permutation generation
  • Branch and bound optimization

πŸ“… Review Schedule

DayFocusTime
0Full read + Activity Selection90 min
1Quick Reference10 min
3Implement Huffman25 min
7Job scheduling exercises20 min
14Debug exercise + proofs15 min
30Interview questions15 min