Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chapter 139: Complexity Handbook

Prerequisites

  • Basic understanding of algorithms
  • Familiarity with Big-O notation

Interview Frequency: ★★★★★

This chapter is a comprehensive reference for time and space complexity of common algorithms and data structures. Use it to quickly look up complexities when designing solutions or analyzing performance.


139.1 Understanding Complexity

Big-O Notation

NotationNameMeaning
O(1)ConstantDoesn’t depend on input size
O(log n)LogarithmicHalves the problem each step
O(n)LinearProportional to input size
O(n log n)LinearithmicEfficient sorting complexity
O(n²)QuadraticNested loops over input
O(n³)CubicTriple nested loops
O(2^n)ExponentialDoubles with each input element
O(n!)FactorialPermutations

Amortized vs Average

  • Amortized: The average cost per operation over a sequence (e.g., dynamic array push_back is O(1) amortized, though individual resizes are O(n))
  • Average: Expected cost assuming some input distribution (e.g., quicksort is O(n log n) average)
  • Worst case: Maximum possible cost for any input of size n

Common Misconceptions

StatementReality
“O(n²) is always slower than O(n log n)”For small n, constants matter more
“O(1) means fast”O(1) could be a very large constant
“Worst case is the common case”Average case often dominates in practice
“Space complexity doesn’t matter”Memory is a real constraint

139.2 Sorting Algorithms

AlgorithmBestAverageWorstSpaceStableIn-Place
Bubble SortO(n)O(n²)O(n²)O(1)YesYes
Selection SortO(n²)O(n²)O(n²)O(1)NoYes
Insertion SortO(n)O(n²)O(n²)O(1)YesYes
Merge SortO(n log n)O(n log n)O(n log n)O(n)YesNo
Quick SortO(n log n)O(n log n)O(n²)O(log n)NoYes
Heap SortO(n log n)O(n log n)O(n log n)O(1)NoYes
Counting SortO(n+k)O(n+k)O(n+k)O(k)YesNo
Radix SortO(d(n+k))O(d(n+k))O(d(n+k))O(n+k)YesNo
Tim SortO(n)O(n log n)O(n log n)O(n)YesNo

Key: n = number of elements, k = range of values, d = number of digits

When to Use Which Sort

SituationBest Choice
General purposeQuick Sort (in-place) or Merge Sort (stable)
Nearly sorted dataInsertion Sort or Tim Sort
Small n (< 50)Insertion Sort
Need stabilityMerge Sort or Tim Sort
Integer keys in small rangeCounting Sort
Integer keys with many digitsRadix Sort
Memory constrainedHeap Sort (in-place, O(1) extra)
Guaranteed O(n log n)Merge Sort or Heap Sort

139.3 Data Structure Operations

Arrays and Lists

OperationDynamic ArraySingly Linked ListDoubly Linked List
Access by indexO(1)O(n)O(n)
SearchO(n)O(n)O(n)
Insert at frontO(n)O(1)O(1)
Insert at backO(1) amortizedO(1) with tailO(1) with tail
Insert at middleO(n)O(n) to find + O(1)O(n) to find + O(1)
Delete at frontO(n)O(1)O(1)
Delete at backO(1)O(n)O(1)
Delete at middleO(n)O(n) to find + O(1)O(n) to find + O(1)

Hash Tables

OperationAverageWorst Case
InsertO(1)O(n)
SearchO(1)O(n)
DeleteO(1)O(n)

Worst case occurs with many hash collisions. With a good hash function and resizing, average case dominates.

Trees

OperationBST (balanced)BST (unbalanced)HeapTrie
InsertO(log n)O(n)O(log n)O(m)
SearchO(log n)O(n)O(n)O(m)
DeleteO(log n)O(n)O(log n)O(m)
Min/MaxO(log n)O(n)O(1)O(m·k)
SuccessorO(log n)O(n)O(n)O(m·k)

m = key length (for Trie), k = alphabet size

Stacks and Queues

OperationStackQueueDeque
Push/EnqueueO(1)O(1)O(1)
Pop/DequeueO(1)O(1)O(1)
PeekO(1)O(1)O(1)
SearchO(n)O(n)O(n)

Priority Queues

OperationBinary HeapFibonacci HeapSorted Array
InsertO(log n)O(1) amortizedO(n)
Extract MinO(log n)O(log n) amortizedO(1)
Peek MinO(1)O(1)O(1)
Decrease KeyO(log n)O(1) amortizedO(n)
MergeO(n)O(1)O(n)

139.4 Graph Algorithms

Traversal

AlgorithmTimeSpaceUse Case
BFSO(V+E)O(V)Shortest path (unweighted), level order
DFSO(V+E)O(V)Cycle detection, topological sort, connected components

Shortest Path

AlgorithmTimeSpaceConstraints
BFSO(V+E)O(V)Unweighted
DijkstraO((V+E)log V)O(V)Non-negative weights
Bellman-FordO(VE)O(V)Negative weights, detects negative cycles
Floyd-WarshallO(V³)O(V²)All pairs, dense graphs
SPFAO(VE) avgO(V)Negative weights (faster in practice)

Minimum Spanning Tree

AlgorithmTimeSpaceNotes
KruskalO(E log E)O(V)Sort edges, use DSU
Prim (binary heap)O((V+E)log V)O(V)Better for dense graphs
Prim (Fibonacci heap)O(E + V log V)O(V)Theoretically optimal

Other Graph Algorithms

AlgorithmTimeSpacePurpose
Topological SortO(V+E)O(V)Ordering in DAG
SCC (Kosaraju)O(V+E)O(V)Strongly connected components
SCC (Tarjan)O(V+E)O(V)Strongly connected components
Articulation PointsO(V+E)O(V)Find cut vertices
BridgesO(V+E)O(V)Find cut edges
Bipartite CheckO(V+E)O(V)2-coloring
Max Flow (Dinic)O(V²E)O(V+E)Network flow
Max Flow (Edmonds-Karp)O(VE²)O(V+E)Network flow (simpler)
Hopcroft-KarpO(E√V)O(V)Bipartite matching

139.5 Common Recurrences

RecurrenceSolutionExample Algorithm
T(n) = T(n/2) + O(1)O(log n)Binary search
T(n) = T(n/2) + O(n)O(n)Median finding, quickselect avg
T(n) = T(n-1) + O(1)O(n)Linear scan
T(n) = T(n-1) + O(n)O(n²)Selection sort, insertion sort worst
T(n) = 2T(n/2) + O(1)O(n)Tree traversal
T(n) = 2T(n/2) + O(n)O(n log n)Merge sort, quicksort avg
T(n) = 2T(n/2) + O(n²)O(n²)Certain divide-and-conquer
T(n) = 2T(n-1) + O(1)O(2^n)Fibonacci (naive), Tower of Hanoi
T(n) = T(n-1) + T(n-2) + O(1)O(φ^n) ≈ O(1.618^n)Fibonacci (naive recursive)
T(n) = 4T(n/2) + O(n)O(n²)Karatsuba-like (without optimization)
T(n) = T(n/2) + O(log n)O(log²n)Certain search problems

Solving Recurrences

Method 1: Substitution Guess the solution and prove by induction.

Method 2: Recursion Tree Draw the tree, sum costs at each level, multiply by number of levels.

Method 3: Master Theorem For T(n) = aT(n/b) + O(n^d):

  • If a < b^d: T(n) = O(n^d)
  • If a = b^d: T(n) = O(n^d log n)
  • If a > b^d: T(n) = O(n^(log_b a))

139.6 String Algorithms

AlgorithmTimeSpacePurpose
KMPO(n+m)O(m)Single pattern matching
Z-AlgorithmO(n+m)O(n+m)Pattern matching + Z-values
Rabin-KarpO(n+m) avgO(1)Rolling hash matching
Aho-CorasickO(n+m+z)O(m·k)Multiple pattern matching
Suffix ArrayO(n log n)O(n)Suffix sorting
Suffix AutomatonO(n)O(n)Substring queries
ManacherO(n)O(n)Longest palindromic substring
Lyndon FactorizationO(n)O(n)Minimal rotation, string structure

n = text length, m = pattern length, z = number of matches, k = alphabet size


139.7 Dynamic Programming

ProblemTimeSpaceNotes
FibonacciO(n)O(1)Bottom-up with two variables
Knapsack (0/1)O(nW)O(W)W = capacity
Knapsack (unbounded)O(nW)O(W)Items can repeat
LCSO(nm)O(min(n,m))Rolling array optimization
Edit DistanceO(nm)O(min(n,m))Rolling array optimization
Matrix ChainO(n³)O(n²)Interval DP
LISO(n log n)O(n)With binary search
Coin ChangeO(nS)O(S)S = target sum
Subset SumO(nS)O(S)S = target sum
TSP (bitmask)O(2^n · n²)O(2^n · n)n ≤ 20

139.8 Number Theory

AlgorithmTimeNotes
GCD (Euclidean)O(log(min(a,b)))
LCMO(log(min(a,b)))lcm = a*b/gcd
Sieve of EratosthenesO(n log log n)Find primes up to n
Modular exponentiationO(log n)Fast power
Modular inverseO(log p)Fermat’s little theorem (p prime)
Extended GCDO(log(min(a,b)))Find x,y in ax+by=gcd
Miller-RabinO(k log²n)Primality test
Pollard’s RhoO(n^(1/4))Factorization

139.9 Geometry

AlgorithmTimeNotes
Convex Hull (Graham scan)O(n log n)
Convex Hull (Andrew’s)O(n log n)Simpler implementation
Closest PairO(n log n)Divide and conquer
Point in PolygonO(n)Ray casting
Line IntersectionO(1)Two lines
Sweep LineO(n log n)Many intersection/overlap problems

139.10 Space Complexity Patterns

PatternSpaceExample
No extra spaceO(1)Two pointers, in-place algorithms
Hash set/mapO(n)Caching, frequency counting
DP tableO(n²) or O(n)With rolling array
Graph adjacency listO(V+E)
Graph adjacency matrixO(V²)Dense graphs
Recursion stackO(depth)DFS: O(V), balanced tree: O(log n)
Priority queueO(V)Dijkstra, Prim
DSUO(V)Union-Find

139.11 Complexity Comparison Chart

Operations  | n=10    | n=100    | n=10³    | n=10⁶    | n=10⁹
────────────┼─────────┼──────────┼──────────┼──────────┼─────────
O(1)        | 1       | 1        | 1        | 1        | 1
O(log n)    | 3       | 7        | 10       | 20       | 30
O(n)        | 10      | 100      | 10³      | 10⁶      | 10⁹
O(n log n)  | 33      | 664      | 10⁴      | 2×10⁷    | 3×10¹⁰
O(n²)       | 100     | 10⁴      | 10⁶      | 10¹²     | 10¹⁸
O(n³)       | 10³     | 10⁶      | 10⁹      | 10¹⁸     | 10²⁷
O(2^n)      | 10²⁴    | 10³⁰     | 10³⁰¹    | ∞        | ∞

Practical limits (assuming 10⁸ operations/second, 1 second time limit):

  • O(n) → n ≤ 10⁸
  • O(n log n) → n ≤ 10⁷
  • O(n²) → n ≤ 10⁴
  • O(n³) → n ≤ 500
  • O(2^n) → n ≤ 25

139.12 Exercises

  1. Determine the complexity of the following code:
for (int i = 1; i < n; i *= 2)
    for (int j = 0; j < n; j++)
        // O(1) work

Answer: O(n log n) — outer loop runs log n times, inner loop runs n times.

  1. Determine the complexity:
for (int i = 0; i < n; i++)
    for (int j = i; j < n; j++)
        // O(1) work

Answer: O(n²) — sum of 1+2+…+n = n(n+1)/2.

  1. What’s the time complexity of building a heap from an unsorted array? Answer: O(n) — not O(n log n)!

  2. Compare the space complexity of recursive vs iterative Fibonacci. Answer: O(n) stack vs O(1).

  3. If an algorithm runs in O(n²) time and processes 10⁴ elements in 1 second, how many elements can it process in 10 seconds? Answer: ~31,623 (since (31623)² ≈ 10×(10⁴)²).


139.13 Interview Questions

  1. “What’s the time complexity of quicksort?” — Average O(n log n), worst O(n²). Worst case happens with already sorted input and bad pivot selection.

  2. “Is O(n log n) always better than O(n²)?” — No. For small n, the constant factor matters. Insertion sort (O(n²)) beats merge sort (O(n log n)) for n < ~50.

  3. “What’s the complexity of hash table operations?” — Average O(1), worst O(n) with many collisions. Amortized O(1) with resizing.

  4. “How do you analyze recursive algorithms?” — Write the recurrence relation, then solve using substitution, recursion tree, or the Master Theorem.

  5. “What’s the space complexity of BFS?” — O(V) for the queue and visited set. In the worst case (star graph), the queue holds O(V) vertices.

  6. “Can an algorithm have different time and space complexity trade-offs?” — Yes! You can often trade space for time (memoization) or time for space (recomputing).


139.14 Cross-References

  • Sorting: Chapter on Sorting Algorithms
  • Graph Algorithms: Chapters on BFS, DFS, Dijkstra, etc.
  • Data Structures: Chapters on Hash Maps, Trees, Heaps, etc.
  • DP: Chapter on Dynamic Programming
  • String Algorithms: Chapters on KMP, Aho-Corasick, Suffix Arrays
  • Number Theory: Chapter on Modular Arithmetic, Primes
  • Algorithm Selection: Chapter 140 (Algorithm Selection Guide)
  • Data Structure Selection: Chapter 141 (Data Structure Selection Guide)

Summary

CategoryKey Insight
SortingO(n log n) is optimal for comparison sorts
SearchingHash O(1) avg, BST O(log n), Array O(n)
GraphsBFS/DFS O(V+E), Dijkstra O((V+E)log V)
DPDepends on state count × transition cost
StringsMost run in O(n) or O(n log n)
RecurrencesMaster Theorem for T(n) = aT(n/b) + O(n^d)
Practical limit~10⁸ operations per second