skip to content

Why is it wrong to call an early-exit duplicate scan over a transaction batch O(1)?

level: juniorimportance: must knowfreq 70%

answer

  1. Ask which input produces that number
  2. What if the batch has no repeats?
  3. Three cases mean three different inputs
  4. Early exit is the lucky input
  5. Worst case is the reportable bound

basics

~10 s

O(1) describes only the best case, where the repeat appears immediately. An early-exit duplicate scan is O(n): a batch with no repeats forces reading every record, and that worst case is what you report.

solid answer

~40 s

The three cases describe different inputs to the same algorithm, and `O(1)` here is only the luckiest one. If the second record repeats the first, the scan returns after two reads — best case. If the batch contains no repeat at all, or the only repeat is the final pair, every record is read: `O(n)` worst case. The average sits between them, but only relative to an assumed distribution of how duplicate-dense batches are, which is a claim about your traffic rather than about the algorithm. Engineering quotes the worst case by default because it is the only bound that holds without assuming anything about the input, and capacity planning has to survive the clean batch, not the lucky one.

code

pseudocode · 6 lines
pseudocode
seen = empty set
for i in 0..n-1:
    if id[i] in seen:
        return true            // early exit
    insert id[i] into seen
return false

go deeper

for a junior

Be ready to name the input that produces each case and to say which one you would report. The habit to build: a complexity number means nothing until you say which input it describes.

for a middle

Explain that the average case is defined over an assumed input distribution while the worst case assumes nothing, and show how this one scan moves from constant to linear purely by changing the batch.

for a senior

Show where this bites in production: timeouts and capacity are sized from the worst case while dashboards show the lucky common case, so an early-exit routine looks free right up until traffic stops containing repeats.

for a principal

Own the convention that designs and interfaces state a worst-case bound plus a measured typical case, so no downstream team ever plans capacity from a best-case number someone quoted once in a document.

### The three cases describe three inputs, not three algorithms Complexity analysis fixes one algorithm and then asks how its cost varies **across the inputs of a given size n**. That question has three standard answers, and they differ only in how you collapse the many possible inputs into one number: - **Best case** — the minimum cost over all inputs of size n. It names the luckiest input. - **Worst case** — the maximum cost over all inputs of size n. It assumes nothing about which input arrives. - **Average case** — the mean cost over an *assumed probability distribution* on inputs of size n. It is only as meaningful as that assumed distribution. All three are functions of n, and all three can be written with any asymptotic notation. "Best case O(1)" and "worst case O(n)" are statements about the same code; the difference lives entirely in which input you quantified over. ### Applying that to an early-exit duplicate scan Take a scan over a batch of n transaction identifiers that returns as soon as it sees an identifier it has already recorded, assuming the membership test itself costs constant time: - **Best case:** the second identifier repeats the first. Two reads, one membership test, return. That is O(1). - **Worst case:** the batch contains no repeat at all, or the only repeat is the final pair. Every identifier is read and recorded before the routine can answer. That is O(n). - **Average case:** somewhere between, but the value depends entirely on how duplicate-dense you assume batches are and how early the first repeat tends to appear. Change your traffic mix and the average moves while the algorithm does not. Notice what the early exit does and does not buy. It makes many *real* runs cheap. It does not change the bound, because a "no duplicates" batch is a perfectly ordinary input and the routine must still read all of it before it can say "no". An algorithm that must answer "no" has to have looked at everything. ### Why engineering quotes the worst case by default The worst case is the only one of the three that needs no assumptions. A best-case number is an existence claim ("some input costs this little"), and an average-case number is a conditional claim ("if inputs look like *this*, the mean is that"). A worst-case number is a universal claim: no input of size n costs more. Capacity planning, timeout selection and deadline analysis all need the universal claim, because the system has to survive the bad batch, not the lucky one. This is also why quoting the best case in a design document quietly misleads. Written as "duplicate detection is O(1) thanks to early exit", it reads as a guarantee to anyone skimming, and the reader who sizes a timeout from it will be surprised on the first clean batch — which, in a healthy pipeline, is most batches. If the early exit really does dominate observed behaviour, the honest sentence names both: "O(n) worst case; in current traffic roughly 90% of batches exit within the first few hundred records." ### The space dimension has the same trap Cost is not only time. The same scan stores each unseen identifier, so its best-case space is O(1) and its worst-case space is O(n) — reached by exactly the input that also costs the most time. A memory budget derived from the typical duplicate-dense batch will be wrong for the batch that has no duplicates at all. Whenever you quote a case, quote it for every resource that matters. ### Common ways this goes wrong in an interview Three failure modes recur. The first is calling the routine O(1) because it *can* return early — confusing "there exists a cheap input" with "the cost is cheap". The second is treating the average as the midpoint of best and worst; it is a weighted mean over a distribution and can sit arbitrarily close to either end. The third is asserting that "big-O always means worst case". Notation and case are independent axes: you choose an upper, tight or lower bound *and* you choose which input set you quantified over, and a claim is only precise when both are stated. ### The habit worth taking away When someone hands you a complexity number, the first question is not "is that right?" but **"which input does that describe?"** For an early-exit routine the answer is usually "the luckiest one", and the number you can plan against is the one for the input that never exits early at all.

  • When is quoting the best case actually useful?
    When the best case is the common case and you can say why. If production batches are known to be duplicate-dense, most runs really do exit in the first few records, and that is worth writing down because it drives observed latency. But you write it as an observation about your traffic alongside the O(n) bound, never as the algorithm's guarantee.
  • Does the average case of this scan depend on the algorithm or on your data?
    On your data. Average-case complexity is a mean over an assumed distribution of inputs — here, how likely a repeat is and how early it appears. Change the traffic mix and the average moves while the code does not, which is why an average-case number is only as dependable as the distribution you claim for it.
  • What is the worst-case space cost of this scan?
    O(n). With no repeats, every identifier in the batch is recorded before the scan finishes, so the memory budget must cover the duplicate-free batch. The best case stores a single element, which is the same trap in the space dimension — quote the case for every resource that matters, not just time.

Quoting the best case is like quoting your commute from the one morning the roads were empty. The schedule still has to survive rush hour.

saying these in an interview costs you the question

  • Calls it O(1) because it can return early
  • Treats the best case as the algorithm's guarantee
  • Thinks average case is the midpoint of best and worst
  • Confuses which case is analyzed with which notation is used
  • Forgets that a duplicate-free batch reads every record

context