Big O Notation
Big O describes how an algorithm's performance scales as the input size grows. It measures the worst-case growth rate, ignoring constants and lower-order terms.
Common Complexities
| Big O | Name | Example |
|---|---|---|
| O(1) | Constant | Array index access |
| O(log n) | Logarithmic | Binary search |
| O(n) | Linear | Loop through array |
| O(n log n) | Linearithmic | Merge sort, Array.Sort |
| O(n^2) | Quadratic | Nested loops |
| O(2^n) | Exponential | Naive Fibonacci |
C# Examples
// O(1) — Constant
int first = arr[0];
// O(log n) — Logarithmic
int idx = Array.BinarySearch(sorted, target);
// O(n) — Linear
foreach (var item in list)
Console.WriteLine(item);
// O(n log n) — Linearithmic
Array.Sort(data);
// O(n^2) — Quadratic
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
Console.Write("*");
// O(2^n) — Exponential
int Fib(int n) => n <= 1 ? n : Fib(n-1) + Fib(n-2);
Practical Tips
- Drop constants: O(2n) is just O(n)
- Drop lower terms: O(n^2 + n) is just O(n^2)
- Nested loops multiply: Two nested loops over n = O(n^2)
- Sequential code adds: O(n) + O(m) = O(n + m)
- Halving = logarithmic: If you cut the problem in half each step, it's O(log n)
Space Complexity
Big O also applies to memory usage:
// O(1) space — modifies array in place
Array.Sort(data);
// O(n) space — creates a new array
var copy = data.ToArray();
// O(n) space — recursion uses stack frames
void Recurse(int n) {
if (n == 0) return;
Recurse(n - 1);
}