Big-O notation describes how an algorithm's run time scales with input size .
Common complexity classes
| Big-O | Name | Example |
|---|---|---|
| Constant | Array index access | |
| Logarithmic | Binary search | |
| Linear | Single loop | |
| Linearithmic | Merge sort | |
| Quadratic | Nested loops | |
| Exponential | Brute-force subsets |
How to determine complexity
- A single
forloop over items → . - A nested
forloop (both over ) → . - Halving the problem each step → .
Space complexity measures memory usage by the same logic.
Practical example — Computing all pairwise distances between particles:
# O(n^{2}) — unavoidable for all-pairs
for i in range(n):
for j in range(i + 1, n):
dist = np.linalg.norm(pos[i] - pos[j])
For large , algorithms like Barnes-Hut () use spatial trees to approximate distant interactions.
Physics link: Molecular dynamics with particles requires force evaluations per time step. Reducing this to via fast multipole methods enabled simulations of millions of atoms.
Common pitfall: Big-O hides constants: an method can beat an one on small inputs. Complexity classes predict scaling, not which code wins today’s benchmark.