Greedy algorithms — exchange-argument proofs, when greedy beats DP, classic patterns (interval scheduling, Huffman, scheduling).
Scanned 8/31/2026
Install to Claude Code
npx -y skills add 0bserver07/chimera --skill greedy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Greedy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/0bserver07-greedy)More formats (shields.io, HTML) on the badges page.
---
name: algo-greedy
description: Greedy algorithms — exchange-argument proofs, when greedy beats DP, classic patterns (interval scheduling, Huffman, scheduling).
when-to-use: "Interval scheduling, activity selection, minimum-spanning-tree weights, Huffman codes, fractional knapsack, scheduling with deadlines."
---
## Greedy — locally best, prove globally optimal
Greedy algorithms make the locally optimal choice at every step
and never reconsider. They are the right tool when an "exchange
argument" works: any optimal solution can be transformed into the
greedy solution without losing optimality.
### Invariants
* The greedy choice is *safe*: there exists an optimal solution
consistent with that choice.
* The remaining problem is the same shape (optimal substructure)
but smaller.
* If you cannot prove safety, greedy is probably wrong — DP or
search is the fallback.
### Complexity
* Most greedy algorithms are dominated by an `O(n log n)` sort
step.
* Min-heap based greedy (Dijkstra, Prim, Huffman) is
`O((V + E) log V)` or `O(n log n)`.
* Linear-scan greedy (jump game, gas station) is `O(n)`.
### Template — Python (interval scheduling — earliest end time)
```python
def max_non_overlapping(intervals: list[tuple[int, int]]) -> int:
"""Maximum number of non-overlapping intervals (start, end)."""
intervals.sort(key=lambda iv: iv[1]) # sort by end
count = 0
end = float("-inf")
for s, e in intervals:
if s >= end:
count += 1
end = e
return count
```
The exchange-argument proof: pick any optimal schedule's first
interval `O`; replace it with the earliest-ending interval `G`.
`G` ends no later than `O`, so the rest of the schedule still
fits. Repeat. The greedy schedule has at least as many intervals.
### Template — Python (Huffman coding — repeatedly merge two smallest)
```python
import heapq
def huffman_cost(weights: list[int]) -> int:
"""Total cost of an optimal binary prefix code (sum of code lengths × freq)."""
heap = list(weights)
heapq.heapify(heap)
total = 0
while len(heap) > 1:
a = heapq.heappop(heap)
b = heapq.heappop(heap)
total += a + b
heapq.heappush(heap, a + b)
return total
```
The merging-pair argument: in *any* optimal prefix tree, the two
lowest-frequency leaves are siblings at the deepest level.
Merging them into one node reduces the problem by 1, and the
optimal solution to the sub-problem extends to the original.
### Template — JavaScript (jump game — farthest reachable)
```javascript
function canJump(nums) {
let reach = 0;
for (let i = 0; i < nums.length; i++) {
if (i > reach) return false; // cannot reach i
reach = Math.max(reach, i + nums[i]); // extend horizon
}
return true;
}
```
`reach` is the invariant: "farthest index reachable from the
prefix `[0..i]`". Each step either extends the horizon or fails.
### Common pitfalls
* **Greedy on the wrong key.** "Earliest end" works for interval
scheduling; "shortest" or "earliest start" do not. Test small
counterexamples before coding the production version.
* **Greedy where DP is needed.** Coin change with arbitrary
denominations is the canonical DP-vs-greedy trap: `[1, 3, 4]`,
target 6 — greedy picks 4+1+1 (3 coins), DP picks 3+3 (2 coins).
* **Forgetting the sort.** Most greedy algorithms hinge on a sort
by the right key. Skipping it gives wrong answers on adversarial
input.
* **Tie-breaking matters.** Two intervals ending at the same time:
pick the one with the latest start to maximise headroom. The
default sort is stable but not necessarily optimal — be explicit.
* **Reasoning by example.** Two examples can both work and your
greedy still be wrong on the third. Demand an exchange argument
or a counterexample search.
### Test corner cases
* Empty input.
* Single element.
* All elements identical.
* Adversarial ordering (reverse-sorted, alternating).
* Ties at the greedy-key — ensure tie-breaking is correct.
* Edge-of-range constraints (interval ending exactly when next
starts — does the schedule allow it?).
When the problem says "minimum number of X" or "maximum number of
non-conflicting Y", greedy is a strong first guess. When it says
"minimum cost to achieve goal Z", DP is the safer first guess.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!