mirror of
https://github.com/prdlk/leetcode.git
synced 2026-09-17 07:26:27 +00:00
docs(docs): add and expand algorithm documentation
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
---
|
||||
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
|
||||
Reference in New Issue
Block a user