"How do you analyze the time and space complexity of an algorithm?"
Complexity analysis is the foundation of algorithm interviews. Every coding question at FAANG and major Chinese tech companies requires you to analyze and optimize your solution's complexity. It tests your ability to evaluate trade-offs between different approaches and choose the most efficient solution.
Define Big O notation: describes the upper bound of an algorithm's growth rate as input size increases. It focuses on the dominant term and ignores constants.
Walk through common complexities: O(1) constant, O(log n) logarithmic, O(n) linear, O(n log n) linearithmic, O(n^2) quadratic, O(2^n) exponential, O(n!) factorial.
Explain analysis techniques: count the number of basic operations as a function of input size, identify nested loops, recursive calls, and divide-and-conquer patterns.
Cover space complexity: account for auxiliary space used (variables, data structures, recursion stack). In-place algorithms use O(1) extra space.
Discuss amortized analysis and common optimizations: hash maps for O(1) lookup, sorting to enable binary search, two pointers to reduce from O(n^2) to O(n).
Big O notation describes how an algorithm's runtime or space usage grows relative to input size n. We focus on the worst case and dominant terms — O(3n^2 + 5n + 10) simplifies to O(n^2) because n^2 dominates as n grows large. Common complexities from best to worst: O(1) is constant time (hash table lookup, array index access); O(log n) is logarithmic (binary search — each step halves the search space); O(n) is linear (single loop through an array); O(n log n) is typical of efficient sorting algorithms (merge sort, quicksort average case); O(n^2) means nested loops over the same data (bubble sort, checking all pairs); O(2^n) is exponential (recursive Fibonacci without memoization, generating all subsets); O(n!) is factorial (generating all permutations). To analyze code: single loop over n elements is O(n), two nested loops are O(n^2), a loop that halves each iteration is O(log n). For recursion, use the Master Theorem: T(n) = aT(n/b) + O(n^d). If d < log_b(a), it is O(n^(log_b(a))); if equal, O(n^d * log n); if greater, O(n^d). Space complexity counts extra memory used — an array of size n is O(n) space, recursion with depth n uses O(n) stack space. Common optimization patterns: use a hash map to convert O(n^2) brute force to O(n) (two-sum problem), sort the array first to enable binary search or two pointers, use dynamic programming to avoid recomputation (exponential to polynomial). Amortized analysis considers the average cost over a sequence of operations — ArrayList's add is O(1) amortized despite occasional O(n) resizing.
After solving any interview problem, always state the time and space complexity without being asked — it shows professionalism.
Know the complexities of standard library operations: HashMap get/put is O(1) average, TreeMap is O(log n), sorting is O(n log n).
Practice the "can we do better?" optimization question — start with brute force and improve.
Use HireMe AI during algorithm practice to verify your complexity analysis.
Best case is the minimum operations (rarely useful), worst case is the maximum (Big O), average case is expected operations over all inputs. Quicksort: best/average O(n log n), worst O(n^2).
The average cost per operation over a sequence. ArrayList.add() is O(n) when resizing but O(1) for most calls, so amortized O(1). Amortized is different from average case — it guarantees the total cost.
For n=10,000: O(n log n) is ~130,000 operations, O(n^2) is 100,000,000. For n=1,000,000: O(n log n) is ~20 million, O(n^2) is 1 trillion. The difference grows dramatically with input size.
HireMe AI listens to your interview in real-time, detects questions, and generates instant answer suggestions — so you never freeze up again.
Try HireMe AI Free