BeeTool.Dev - Essential Tools for developers

Stories.Tool Tabs VaultPersonal Documents
Super Debugging Context
BeeTool.Dev

Essential tools, knowledge, and playgrounds for developers.

Explore

  • Stories
  • Personal Documents
  • Features
  • Algorithms Playground

Tool Tabs

  • JSON Compare
  • SQL Formatter
  • Text Diff
  • All tools →

Learn

  • Sorting algorithms
  • Searching algorithms
  • Algorithm Race Mode
© 2024 – 2026 BeeTool.DevPrivacy policy
← Algorithms Playground
Searching · Beginner

Linear Search

Walk the array front to back and compare every element — zero preconditions, zero setup, and unbeatable when the data is small or unsorted.

AverageO(n)StructureArrayNeeds sortedNoComparisonYes
Must remember

Scan left to right, compare everything, stop on the first match.

Best O(1) · Avg O(n) · Worst O(n) · Space O(1)

Hands on Interactive visualization

Size 24
Target 14
ProbingFoundUnexploredEliminated
0/0Ready — press play
Speed
Step 0 / 0
Comparisons
0
Swaps
0
Reads
0
Writes
0
Elapsed
0.0s
Frames
0
Depth
0 / 0
Aux memory
0 B

Implementation Code

export function linearSearch(a: number[], target: number): number {
  for (let i = 0; i < a.length; i++) {
    if (a[i] === target) return i; // first match wins
  }
  return -1; // exhausted the array: definitively absent
}

Big-O Complexity

Best
O(1)
Average
O(n)
Worst
O(n)
Space
O(1)

Average is n/2 comparisons for a uniformly placed hit and n for a miss — but the constant per comparison is tiny and the access pattern is perfectly cache-friendly.

In production When to use

Small collections

Below a few dozen elements, a linear scan beats binary search in practice: no branching subtleties, no sort precondition, and the whole array often fits in one or two cache lines.

Unsorted / one-shot data

Searching once through unsorted data is O(n) — sorting first costs O(n log n). Any single lookup over data you will not query again should be a plain scan.

Stdlib primitives

Array.prototype.indexOf and includes in JavaScript, list.index and the in operator on Python lists, and slices.Index in Go are all linear scans under the hood.

Predicate search

Finding the first element matching an arbitrary condition — Array.prototype.find, C++ std::find_if, Rust Iterator::position — is inherently linear because the predicate imposes no order to exploit.

Hardware / SIMD scans

Columnar databases and analytics engines scan compressed column chunks with vectorized (SIMD) linear passes — a predictable sequential read that prefetchers and vector units love.

Linked structures

Linked lists and singly-chained hash buckets have no random access, so linear traversal is the only option — which is exactly why hash chains are kept short.

Trade-offs Strengths & weaknesses

  • No preconditions: works on unsorted, heterogeneous, or streaming data.
  • O(1) space and trivially correct — hard to get wrong in an interview or in production.
  • Sequential access is the friendliest possible pattern for CPU caches and prefetchers.
  • Works on structures without random access: linked lists, iterators, streams.
  • Supports arbitrary predicates, not just equality on a sorted key.
  • Fastest option in absolute terms for small n — often up to tens of elements.
  • O(n) per lookup — untenable for repeated queries over large data.
  • Ignores any structure the data already has (sortedness, index, hash).
  • Miss cost is always the full n comparisons.
  • Repeated scans over big arrays evict useful data from cache.
  • n lookups over n elements is O(n²) — the classic accidental-quadratic bug.

Intuition Mental model

Checking every box on a shelf

You are looking for one labeled box in a storeroom with no ordering system. The only reliable plan: start at one end and check every box until you find it or run out of shelf.

  1. Start at the leftmost box — no ordering means no smarter starting point exists.
  2. Read each label and compare it to the one you want; move right on a mismatch.
  3. The moment a label matches, stop — that is the best-case O(1) hit at the front.
  4. Reach the end of the shelf without a match and you know, with certainty, it is not there.
  5. On average you inspect half the shelf for a hit and the whole shelf for a miss — that is the O(n).

Prep Interview questions

When does linear search beat binary search in practice?
Small n (branch-predictable sequential reads beat log n random probes), unsorted data queried once, and linked structures with no random access. Benchmark crossover is typically tens of elements.
How do you find the first element matching a predicate, and can you do better than O(n)?
You cannot in general — an arbitrary predicate gives no ordering to exploit, so every element is a potential answer. Lower bound is Omega(n) for a miss.
What is the sentinel optimization for linear search?
Place the target in a spare slot past the end so the loop needs no bounds check — only one comparison per iteration instead of two. A classic micro-optimization from Knuth.
You call list.contains inside a loop over another list. What just happened?
An accidental O(n·m) — each contains is a hidden linear scan. Hoist one side into a hash set to get O(n + m).
How would you parallelize a linear search over a huge array?
Chunk the array across threads, each scans its slice, first hit wins via an atomic flag or early-exit signal. Embarrassingly parallel because chunks are independent.

Watch out Common bugs

Returning the wrong sentinel on a miss

Returning 0 (a valid index) instead of -1, or null instead of undefined, silently turns misses into hits at index 0. Pick one miss convention and test it explicitly.

Hidden linear scans inside loops

indexOf, includes, or list.remove(value) inside a loop is O(n) per call — the outer loop makes it quadratic. Profile-visible only once the data grows.

Off-by-one on the loop bound

i <= n instead of i < n reads one element past the end — undefined behavior in C-family languages, a panic in Rust, undefined in JavaScript.

Comparing with the wrong equality

Reference equality instead of value equality (== on Java strings, is on Python objects) makes structurally equal targets invisible to the scan.

One screen Cheat sheet

Scan left to right, compare everything, stop on the first match.

Best O(1) · Avg O(n) · Worst O(n) · Space O(1)
  • The only search with zero preconditions — unsorted data, streams, linked lists, predicates.
  • Beats binary search on small arrays thanks to sequential, cache-friendly access.
  • indexOf / includes / in are linear scans — calling them in a loop is O(n²).
  • Miss always costs the full n comparisons.
  • Sentinel trick removes the bounds check for one comparison per step.
  • For repeated lookups, build a hash set or sort once instead.
Pick whenData is small, unsorted, queried once, or only reachable sequentially.
Avoid whenYou query the same large collection repeatedly — hash it or sort it first.

Binary Search