Why is linear search still O(n) even though it exits early on the first match?
answer
- think about which case sets the bound
- what happens when nothing matches
- best, average and worst all differ here
- n/2 is only a constant factor
- big-O describes growth, not a lucky run
basics
~20 sLinear search is O(n) because the bound is set by the worst case: a match in the last position, or no match at all, forces a scan of every element. Early exit improves lucky runs, not the growth rate.
solid answer
~50 sBig-O describes an upper bound on how cost grows, and for a sequential scan the worst case is unavoidable: the target sits last, or it is absent. Early exit gives a best case of O(1) and, if the target is present and equally likely at any position, an expected `n/2` comparisons — but `n/2` is a constant factor away from `n`, so the class is still linear. The important asymmetry is that **you cannot early-exit out of a negative result**: proving a record is absent requires examining every element. In a triage scan over a buffer of about thirty captured packet records looking for the first malformed checksum, early exit is a real practical win when malformed records are common and near the front — and buys nothing on the clean buffers, which are the common case.
go deeper
Be ready to state best, average and worst case for a sequential scan and say which one the O(n) label comes from. Say out loud that a miss examines everything.
Explain why n/2 is a constant factor rather than a complexity class, and why the average depends on an assumed input distribution rather than on the algorithm itself.
Show that you reason about workload shape: a validation pass that usually finds nothing pays the worst case on nearly every call, so the tail, not the average, is what your latency budget sees.
Own the framing that asymptotic labels are not runtime predictions. Decide when a linear cost is acceptable for the sizes your systems actually carry, and make that assumption explicit and monitored rather than folklore.
## What linear search actually does A linear (sequential) search walks a collection from one end to the other, testing each element against a predicate or a target key, and stops the moment the test succeeds. It makes no assumptions about the data: no ordering, no index, no precomputation. That is its whole selling point — it is the only search that works on arbitrary unsorted input, and it is the baseline every cleverer search is measured against. ## The three cases - **Best case, O(1):** the target is the first element examined. One comparison, done. - **Average case, about n/2 comparisons:** if the target is present and equally likely to be at any position, the expected number of comparisons is `(n+1)/2`. - **Worst case, O(n):** the target is in the last position examined, or it is not there at all. Every element is tested. The complexity label attaches to the worst case, so the algorithm is O(n) — and, because there are inputs that genuinely require touching every element, it is also Θ(n) in the worst case rather than merely bounded by it. ## Why n/2 is not a better complexity class This is the misconception the question exists to kill. Asymptotic notation deliberately discards constant factors, because they depend on machine, data layout and comparison cost rather than on the algorithm's structure. `n/2` and `n` grow the same way: double the input, double the work. Halving the constant is a genuine engineering win — it is not a change of complexity class, and it never closes the gap with a logarithmic search as `n` grows. Writing "O(n/2)" is a category error; the notation has already thrown that factor away. There is a second, subtler point hiding in "average case". `n/2` is a claim about the **inputs**, not about the algorithm: it assumes the target is present and uniformly positioned. Change the distribution and the number changes with it. A workload where most lookups miss has an average of exactly `n` comparisons, because every miss is a full scan. A workload where the hot handful of records is kept at the front has an average close to 1. Neither is a property of linear search; both are properties of how the data is arranged and queried. (Note that average-case reasoning is also distinct from *amortized* reasoning: amortized bounds total cost over a worst-case *sequence* of operations and assume nothing about input distribution.) ## The asymmetry that matters in practice Early exit is a one-sided optimization. It can only shorten a **successful** search. An unsuccessful search — proving that nothing in the buffer matches — has no shortcut available: absence is only established by exhaustion. This is why the shape of your workload determines whether early exit is worth talking about at all. Consider a packet-capture triage tool scanning an unsorted buffer of roughly thirty captured records for the first one with a bad checksum. If corruption is common, early exit fires quickly and the average scan is short. But the interesting operational case is the clean buffer, where the tool must inspect all thirty records to report "no malformed packets" — and that is the case that runs on every healthy capture, which is most of them. A validation pass that usually succeeds pays the worst case almost every time. So the honest description is not "it's fast because it exits early"; it is "successful lookups are often short, and every clean pass costs a full scan". ## The direction of the claim Two directions are easy to get backwards, and interviewers listen for both. First, O(n) is an **upper bound on growth**, not a prediction of runtime. Labelling something O(n) does not say it is slow; on a compact buffer of a few dozen fixed-size records, a linear scan is a tight, branch-predictable loop over contiguous memory and can be faster in wall-clock terms than a structure with a better bound. Second, early exit changes *which* case you land in, never *what the cases are*. If someone claims early exit makes the search sublinear, ask them what happens when the element is missing. The answer — every element, every time — is the whole bound. ## What to say in an interview Name the three cases, state that the bound comes from the worst one, point out that `n/2` is a constant factor rather than a class, and then volunteer the asymmetry: successful searches can be short, unsuccessful ones cannot. That last sentence is what separates a memorised answer from an understood one.
- Does early exit help at all when the scan is being used to prove a record is absent?No. Absence can only be established by exhausting the collection, so an unsuccessful search always examines every element. The only ways to make that cheaper are a cheaper per-element test, fewer elements, or a different structure that can answer membership without a scan — early exit is not one of them.
- Is the average of roughly n/2 comparisons a claim about the algorithm or about the input?About the input. It assumes the target is present and uniformly likely at any position. A miss-heavy workload averages a full n comparisons; a workload where hot records sit at the front averages close to 1. The algorithm is identical in all three cases — only the input distribution moved.
- If matches are usually near the front, is it fair to advertise the scan as fast?Only if you say so precisely. Quote the expected cost for your measured distribution separately from the worst case, and remember that tail latency is driven by the full scans — the misses and the late matches. Those are exactly the requests that show up at p99.
Looking for a name on an unsorted guest list: you might get lucky on the first line, but to say with confidence that someone is not on the list you have to read every line.
saying these in an interview costs you the question
- Says early exit makes linear search logarithmic
- Writes O(n/2) as if it were a tighter complexity class
- Assumes a miss also stops somewhere in the middle
- Treats big-O as a prediction of actual runtime
- Thinks the worst case only occurs on adversarial input