Algorithms & Programming

Lesson 1 of 6

Complexity and Core Data Structures

Big-O analysis and the four structures behind most quant coding answers: arrays, hash maps, heaps, and stacks and queues, plus what the coding round actually looks like.

Big-O: how work grows with n

Your system receives 1 million orders a day, and someone proposes comparing every order with every other one to find duplicates. Is that fine? Big-O notation answers this before you write any code. It describes how the number of basic operations grows with the input size nn, dropping constants and lower-order terms, so 3n2+50n+73n^2 + 50n + 7 is O(n2)O(n^2).

Formally, f(n)=O(g(n))f(n) = O(g(n)) means f(n)≤c g(n)f(n) \le c\,g(n) for some constant cc once nn is large enough. That is an upper bound. Ω\Omega is the matching lower bound, and Θ\Theta means both hold, so the growth rate is pinned exactly. In interviews people say "big-O" when they mean Θ\Theta, and that is usually fine.

The classes you will meet, from fast to slow, are O(1)O(1), O(log⁡n)O(\log n), O(n)O(n), O(nlog⁡n)O(n \log n), O(n2)O(n^2) and O(2n)O(2^n). With n=106n = 10^6:

n2=1012,nlog⁡2n≈2×107n^2 = 10^{12}, \qquad n \log_2 n \approx 2 \times 10^7

Even at 10810^8 simple operations per second (compiled code; plain Python is closer to 10710^7), the all-pairs check takes 10410^4 seconds, close to three hours. Sorting by order ID and comparing neighbours is O(nlog⁡n)O(n \log n) and finishes in well under a second.

To find the complexity, count loops. One pass over the data is O(n)O(n). A loop inside a loop over the same data is O(n2)O(n^2). Halving the problem at each step, as binary search does, gives O(log⁡n)O(\log n), because you can halve nn only about log⁡2n\log_2 n times. Also state the space complexity, the extra memory an algorithm uses, since most of the tricks below spend memory to save time.