mirror of
https://github.com/prdlk/leetcode.git
synced 2026-09-16 23:16:26 +00:00
96 lines
2.6 KiB
Plaintext
96 lines
2.6 KiB
Plaintext
---
|
|
title: Greedy Algorithms
|
|
---
|
|
|
|
# Greedy Algorithms
|
|
|
|
## The idea
|
|
|
|
At each step, take the best move *right now*. Never look back.
|
|
|
|
Grokking's example: the classroom problem.
|
|
You want the most classes in one room. Which do you pick?
|
|
**Always pick the class that ends first.** It leaves the most room for the rest.
|
|
|
|
Greedy works only when the local best is *provably* the global best.
|
|
When it works, it beats DP — no memo table, no lookback, often O(n).
|
|
|
|
## The picture
|
|
|
|
```mermaid
|
|
gantt
|
|
dateFormat HH:mm
|
|
axisFormat %H:%M
|
|
section Pick ✓
|
|
Art (ends first) :done, 09:00, 45m
|
|
Math (ends next) :done, 10:00, 60m
|
|
Music :done, 11:00, 60m
|
|
section Skip ✗
|
|
English (overlaps Art) :crit, 09:30, 60m
|
|
CS (overlaps Math) :crit, 10:30, 60m
|
|
```
|
|
|
|
Pick by earliest end time. Skip anything that overlaps a pick.
|
|
|
|
## Kadane's — DP squeezed to one variable (LC 53 — Maximum Subarray)
|
|
|
|
The greedy question at each element:
|
|
"Do I extend the running sum, or start fresh here?"
|
|
If the running sum is negative, it only hurts. Drop it.
|
|
|
|
```python
|
|
def max_sub_array(nums: list[int]) -> int:
|
|
best = current = nums[0]
|
|
|
|
for n in nums[1:]:
|
|
current = max(n, current + n) # extend or restart
|
|
best = max(best, current)
|
|
return best
|
|
```
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
A["-2"] --> B["1<br/>restart"] --> C["-2<br/>extend"] --> D["4<br/>restart"] --> E["3<br/>extend"] --> F["5<br/>extend"] --> G["6<br/>extend ← best"]
|
|
|
|
style G fill:#2e7d32,color:#fff
|
|
```
|
|
|
|
## Jump Game (LC 55) — track the farthest reach
|
|
|
|
One pass. Keep the farthest index you can touch.
|
|
If your position ever passes the reach, you are stuck.
|
|
|
|
```python
|
|
def can_jump(nums: list[int]) -> bool:
|
|
reach = 0
|
|
for i, n in enumerate(nums):
|
|
if i > reach:
|
|
return False # stuck
|
|
reach = max(reach, i + n)
|
|
return True
|
|
```
|
|
|
|
## How to justify greedy in an interview
|
|
|
|
Use an **exchange argument**: "If an optimal answer made a different choice here, I could swap in my greedy choice without making it worse."
|
|
Say this out loud. It is the difference between guessing and proving.
|
|
|
|
## Complexity
|
|
|
|
| | Time | Space |
|
|
|---|---|---|
|
|
| One-pass greedy (Kadane, Jump) | O(n) | O(1) |
|
|
| Sort-then-commit (intervals) | O(n log n) | O(1) |
|
|
|
|
## Close-out ritual
|
|
|
|
Before you submit, say out loud:
|
|
1. Time and space complexity.
|
|
2. One edge case trace: all-negative array, single element, or zero at index 0.
|
|
|
|
## Plan problems
|
|
|
|
**A-set:** LC 53 · 55 · 45 · 134
|
|
**B-set:** LC 122 · 918 · 763
|
|
**Feeds into topic 24 (Intervals):** LC 57 · 56 · 435 · 253
|