Complexity Analysis
How to measure and compare the efficiency of code before ever running it — the analysis toolkit every other DSA topic leans on. Interviewers expect a time and space estimate for every solution you propose, so this vocabulary shows up in nearly every coding round.
part ofData structures & algorithmsoverview, primer and where to startread it →on this pageshowhide
explore
- Asymptotic Notation & Bounds16 questions
- Big-O, Big-Theta, Big-Omega4 questions
- Growth Classes & Dominant Terms4 questions
- Best, Average, Worst & Expected Case4 questions
- Lower Bounds4 questions
- Analyzing Iterative Code8 questions
- Loop Patterns4 questions
- Hidden Costs of Built-ins4 questions
- Analyzing Recursive Code12 questions
- Recurrence Relations4 questions
- Master Theorem4 questions
- Branching & Exponential Recursion4 questions
- Amortized Analysis8 questions
- Dynamic Arrays & Resizing4 questions
- Amortized Reasoning Methods4 questions
- Space Complexity8 questions
- Auxiliary Space & In-Place4 questions
- Recursion Stack Space4 questions
- Constraints-to-Complexity Reasoning4 questions
- Computer Scienceskillanchors this topic
- Data Structures & Algorithmsskillanchors this topic
- AI & Data Scientistrole
- AI Engineerrole
- AI Red Teamingrole
- Android Developerrole
- Backend Developerrole
- Blockchain Developerrole
- Cyber Security Expertrole
- Data Analystrole
- Data Engineerrole
- DevOps / SRE Engineerrole
- DevSecOps Engineerrole
- Forward Deployed Engineerrole
- Frontend Developerrole
- Full Stack Developerrole
- Game Developerrole
- Java Backend Developerrole
- Java SDETrole
- Kotlin Backend Developerrole
- MLOps Engineerrole
- Machine Learning Engineerrole
- Network Engineerrole
- PostgreSQL DBArole
- QA Engineerrole
- Software Architectrole
- iOS Developerrole
questions
page 2 of 2Why is it a misconception that Big-O notation means worst-case running time?
basics
~20 sBig-O bounds the growth of a function; the case — best, worst, average — chooses which function you bound. They are independent axes: a worst case can have O, Theta, and Omega bounds, and a best case can meaningfully be Omega(n).
For a randomized routing algorithm, how does expected-case complexity differ from average-case?
basics
~20 sExpected case averages over the algorithm's own random choices, so it holds for every input. Average case averages over an assumed input distribution and collapses if that assumption is wrong. Randomization moves the uncertainty from the data to the coin flips.
Why can't O(E+S) over E events and S servers be simplified to O(E)?
basics
~20 sE and S are independent inputs, so neither provably dominates the other. Lower-order terms may only be dropped within a single variable. O(E+S) becomes O(E) only when the problem guarantees S is bounded by a multiple of E.
How do you decide whether brute-forcing all n! orderings or all 2^n subsets is feasible?
basics
~20 sDo the arithmetic instead of labelling both 'exponential'. At n=12 there are 4,096 subsets but 479 million orderings — a gap of five orders of magnitude. Subsets stay tractable to roughly n=25-30; orderings die around n=12-14.
Why can't the master theorem solve T(n) = T(n-1) + O(n), and what does?
basics
~20 sThe master theorem covers only T(n) = a·T(n/b) + f(n), where a subproblem is n divided by a constant b above 1. Subtracting one leaves no such b, so no case applies. Summing the per-call work gives Θ(n^2).
When you unroll T(n)=2T(n/2)+cn by substitution, what stops the expansion and sets the log factor?
basics
~20 sThe base case stops it. After k substitutions the expression reads 2^k·T(n/2^k) + k·cn; you stop when n/2^k hits the base-case size, at k = log2 n. That is where the accumulated cn per round becomes cn log n.
When does memoizing a pricing calculation stop paying for the memory it consumes?
basics
~20 sMemoization pays only when the same key is requested repeatedly. Its memory is distinct keys reached times bytes per entry, so a wide key space visited once each — every product-and-region pair in a nightly sweep — costs everything and saves nothing.
Your request path uses an amortized O(1) structure but p99 spikes — how do you explain and fix it?
basics
~20 sNothing is violated: an amortized O(1) structure is allowed to let one call absorb work that many cheap calls prepaid, and that call lands in some request's p99. Fix the tail by spreading the bulk step out or moving it off the request path.
Amortized O(1) append still misses a 2 ms deadline on a sensor ingestion buffer — why?
basics
~20 sAn amortized bound covers the total cost of a sequence, not any one call. The append that fills the buffer copies every element, costing Theta(n), and that single call blows a per-operation deadline no matter how good the average is.
A left and right index converge over a timestamp log with swaps inside — why is that loop O(n), not O(n^2)?
basics
~20 sEvery iteration moves at least one index, each index moves in only one direction, and together they can cover at most n positions before meeting. So the loop runs at most n times, whatever the body does per pass.
What lookup guarantee should a hash-based telemetry dedupe service promise in its SLA?
basics
~20 sPromise a measured percentile, not an asymptotic class. A hash lookup is expected O(1) and worst-case O(n) for a single operation, so the SLA states a p99 latency at a named key volume and load, with the distribution assumption written down.
A downsampling pass costs 5n log n + 200n steps — is O(n log n) an honest label?
basics
~20 sFormally yes: for large enough n the 5n log n term dominates. But 200n is the larger term for every n below roughly 10^12, so the label predicts the growth shape, not the runtime anyone will measure.
A sublinear exact duplicate detector over an n-packet stream is proposed — how do you evaluate it?
basics
~20 sAn algorithm that skips even one packet is defeated by an adversary who plants the duplicate there, so exact detection over a raw n-packet stream is Omega(n). A sublinear claim means work moved, the guarantee weakened, or n means something smaller.
Memoizing an exponential recursion doesn't always make it polynomial — how do you tell in advance?
basics
~20 sCount the distinct reachable states the cache key can take, then multiply by the work each state does outside recursion. A key holding a subset of n items has 2^n values — caching helps enormously and still leaves you exponential.
Why does T(n)=2T(n/2)+O(n^2) total Θ(n^2) rather than Θ(n^2 log n)?
basics
~20 sPer-level work halves as you descend: n^2, then n^2/2, then n^2/4. The series sums to under 2n^2, so the root call dominates and the total is Θ(n^2). Multiplying per-call work by depth only works when levels cost the same.
How would you size the seen-set for deduplicating a billion-row clickstream, and what changes when it exceeds RAM?
basics
~20 sSize it as distinct keys times realistic bytes per entry, not raw key bytes: a billion 16-byte keys lands in tens of gigabytes. Above RAM, partition by key hash, order the data so duplicates meet, or accept an approximate filter.
A breadth-first walk of a shallow org chart with 100,000 direct reports exhausts memory, but depth-first does not. Why?
basics
~20 sBreadth-first peak memory is the widest level, depth-first peak memory is the height. A wide, shallow org chart has a frontier of 100,000 nodes but a depth of two or three, so the queue explodes while the recursion barely nests.
With bookings capped at 50, how do you justify shipping the O(n^2) check over the O(n log n) one?
basics
~20 sAt n = 50 the quadratic pass is about 2,500 operations and the alternative about 280 — both invisible, so runtime cannot decide. Correctness risk and maintenance cost do; ship the simple version and enforce the cap.
Would you replace an O(n^2) step with an O(n log n) one when a contract caps input at 5,000 records?
basics
~20 sProbably not on performance grounds alone: at 5,000 records the quadratic step is about 2.5x10^7 element operations, typically tens of milliseconds. Decide on exposure instead — how firm the cap is, what happens when it breaks, and who maintains the harder code.
Your ingest budget forbids touching every packet, yet exact detection is Omega(n) — which guarantee do you weaken?
basics
~20 sA proven lower bound is not the negotiable part, so the only lever is the problem statement: weaken exactness, shrink the input covered, or move the cost off the latency path. Pick the relaxation whose failure mode the business can absorb.
How do you decide whether a recursive parser over user-supplied nested data must be rewritten iteratively?
basics
~20 sDecide by who controls the depth. If the nesting comes from outside your trust boundary it is unbounded, and the fixed stack ceiling becomes a remote crash switch — so cap the accepted depth or keep pending work off the call stack.
Why does finding the maximum of n tournament seeds require at least n-1 comparisons?
basics
~20 sEvery seed except the winner must lose a comparison before it can be ruled out, and one comparison rules out at most one seed. With n-1 to eliminate, no correct algorithm uses fewer than n-1 comparisons.
What does a running-time guarantee of o(n log n) promise that O(n log n) does not, and what may a caller actually rely on?
basics
~20 sLittle-o is strictly stronger: o(n log n) means the running time grows strictly slower than n log n — their ratio tends to zero — while O(n log n) permits growth exactly proportional to n log n. Neither promises anything about constants or small inputs.
For an arbitrary-precision multiply with T(n)=3T(n/2)+O(n), what does the master theorem give and when does it actually beat the quadratic method?
basics
~20 sIt solves to Θ(n^(log_2 3)), about Θ(n^1.585), by case 1: the watershed beats the linear combine, so the leaves dominate. It outruns the quadratic schoolbook method only above a crossover size, because its constants, temporaries and call overhead are far larger.
showing 31–56 of 56