There's a reason greedy algorithms are usually the first optimization strategy anyone reaches for. They mirror how we naturally make decisions: at every step, take the option that looks best right now and trust that the sum of good local choices produces a good global outcome.
The elegant thing is that sometimes this actually works. The frustrating thing is that we rarely know in advance whether it will.
When greed is provably correct
A greedy algorithm is guaranteed to produce an optimal solution only when the problem exhibits two properties: optimal substructure (an optimal solution contains optimal solutions to subproblems) and the greedy choice property (a locally optimal choice is part of some globally optimal solution).
def coin_change_greedy(amount, coins):
coins.sort(reverse=True)
result = []
for coin in coins:
while amount >= coin:
amount -= coin
result.append(coin)
return result
# Works for [25, 10, 5, 1]. Fails for [25, 10, 1] on amount=30.
The coin change problem is the classic cautionary tale. With standard currency denominations, greedy gives the minimum number of coins. Change the denominations slightly and the same algorithm silently returns a worse answer. The code doesn't break—it just stops being optimal.
The danger of greedy thinking isn't that it fails loudly. It's that it succeeds just often enough to earn your trust.
The life metaphor
Most consequential decisions—careers, relationships, where to live—lack the greedy choice property. The locally optimal move (the higher salary, the safer path) frequently forecloses the globally optimal outcome. Intuition is a greedy algorithm running on a problem that doesn't satisfy its preconditions. That mismatch is where most of our regret comes from.