"There are maybe eight complexities you meet in real life. Learn the ladder once and you can place almost any algorithm on it at a glance."
The Ladder, Best to Worst
Ranked from "barely notices the input" to "dies if you sneeze at it":
- O(1) constant — dict lookup, array index, append to a list. The dream. Input size is irrelevant.
- O(log n) logarithmic — binary search, balanced-tree lookup. Halving each step. A billion items in ~30 steps.
- O(n) linear — scan a list, find a max. Touch each item once. Honest and fine.
- O(n log n) linearithmic — the good sorts (merge, Timsort). The realistic ceiling for "process everything, smartly."
- O(n²) quadratic — nested loops, naive sorts, all-pairs. Fine for hundreds, painful for millions.
- O(n³) cubic — naive matrix multiply, triple-nested loops. Already rough at a few thousand.
- O(2ⁿ) exponential — try every subset, naive recursive Fibonacci. Dies around n = 40.
- O(n!) factorial — try every ordering, brute-force traveling salesman. Dies around n = 12.
Make the Gulf Visceral
The names hide how violent the differences are. At n = 50: O(n) is 50 operations, O(n²) is 2,500, O(2ⁿ) is about a quadrillion, and O(n!) is a number with 65 digits — more than the atoms in the observable universe. Same input. The algorithm's shape is the difference between "instant" and "the heat death of the universe finishes first." Run the code below and watch the numbers explode.
The Line You Don't Want to Cross
For everyday data, O(n log n) and below is "sleeps fine at night." O(n²) is "okay until the data grows." Anything exponential — O(2ⁿ), O(n!) — is a fire alarm: it works on your tiny test case and detonates on real input. A huge part of algorithm design (especially the Dynamic Programming track) is dragging an exponential brute force down to a polynomial that actually ships.