All topics
28

Finding an item by scanning a list

Tier 1Free

Where it runs

1. The problem

So far you have done things with arrays: added them up, moved a window, built prefix sums. Now the simplest question of all: is a value in the list, and if it is, where?

If the list has no order at all, there is no shortcut. The item you want could be anywhere. The one safe move is to look at the cells one by one until you find it or the list runs out.

You have a list of 500 user records in the order the users signed up. It is not sorted by any field. Someone asks for the user with id 4092. You have to walk the list and check the id of each record until one matches.

2. In plain words

Back to the 500 users. You need id 4092. You look at the first record: id 17, not it. The second: id 3301, not it. And so on, one at a time. If the record with id 4092 is the 20th, you stop at the 20th.

If there is no such user at all, you find out only at the very end, after you have checked all 500 records. You can't say "no" earlier: any record you haven't checked could be the one.

3. The idea

Walk the list from the first cell to the last. In each cell, compare its value with the one you are looking for. As soon as they match, stop and return that position. That is the answer.

If you reach the end with no match, the value is not in the list. Return -1, which means "not found". Return the position of the first match: a value can appear more than once, and usually the first one is the one people want.

4 2 9 7 1 5 check, check... match at index 3

Trace it on [4, 2, 9, 7, 1, 5], looking for 7.

  • Cell 0 holds 4, not it.
  • Cell 1 holds 2, not it.
  • Cell 2 holds 9, not it.
  • Cell 3 holds 7, a match. Return 3.

That took four checks. Looking for 8 instead, you would check all six cells and return -1.

4. What it costs

Time is O(n). In the worst case the item is last or missing, and you check all n cells. On average you check about half. Either way, the work grows with the length of the list.

Memory is O(1). You keep one loop counter and nothing that grows with the input.

This is the price of an unordered list. The next lessons work with sorted data. In a sorted list, binary search finds an item in about log n checks instead of n. Scanning is the plain starting point that all other methods are compared with.

5. Where this shows up

Array.prototype.indexOf, find and includes in JavaScript, and the in operator on a Python list. Finding the first matching line in an unsorted log or buffer. Finding a setting in a short list, where sorting would cost more than it saves. Any pass of the form "find the first element that meets condition X" over data with no useful order.

Find 8 by checking every element in turn
linearSearch([7, 3, 9, 4, 8, 2], 8)
arr
7
3
9
4
8
2
target = 8i = -return = ?

Find the index of 8. The array is not sorted, so the only way is to check the numbers one by one from the start.

Speed race
Linear and binary search over the same 40 sorted numbers

Bars: the sorted numbers. Both lanes look for one near the end.

One operation is one comparison with the target. Every frame, each lane does the same number of operations, so the slow one falls behind.

Linear search O(n)
0 operations
Binary search O(log n)
0 operations

 

And with more numbers

Operations for n numbers, and roughly how long they take at 100 million simple operations a second. An estimate from the same count, not a measurement.

n = 1,000
Linear search900 · under 1 ms
Binary search10 · under 1 ms
n = 100,000
Linear search90K · under 1 ms
Binary search16.6 · under 1 ms
n = 10,000,000
Linear search9M · 90 ms
Binary search23.3 · under 1 ms

Recognise it

Linear search

Say these words and it is this pattern

  • unsorted array
  • check every element
  • no order guarantee
  • find first/any match
  • small n or one-time scan

Looks similar, isn't

n up to roughly 1e7 gives O(n) time and O(1) space. Bigger, or repeated, wants a real structure.

On LeetCode

Easy problems that ask for the first item, index or place that matches a condition, in data with no useful order. Scan from the start, stop at the first match, and return -1 when there is none.

Your task (Tier 1)

Write the function linearSearch(nums, target).

Go through the list from the start. Return the position of the first number that equals target. If no number matches, return -1.

  • Input: nums, a list of numbers in any order, and target, the number you look for. Example: [4, 2, 9, 7, 1, 5] with target 7.
  • Return: the position of the first match, or -1 if there is no match.

Steps:

  1. Go through the list from left to right, one position at a time.
  2. If the number at this position equals target, return this position right away.
  3. If you reach the end with no match, return -1.

Done when all tests pass:

  • [4, 2, 9, 7, 1, 5], target 7 -> 3 (a match in the middle)
  • [5, 1, 2], target 5 -> 0 (the first number)
  • [1, 2, 3], target 3 -> 2 (the last number)
  • [3, 7, 3, 7], target 7 -> 1 (return the first match)
  • [1, 2, 3], target 9 -> -1 (the number is not in the list)
  • [], target 5 -> -1 (empty list, must not crash)
  • [8], target 8 -> 0 (one number, a match)
  • [8], target 3 -> -1 (one number, no match)

Practice

linearSearch

linearSearch(nums, target) -> index (0-based) of first match, or -1

export function linearSearch(nums, target) {
  // Your code here. The task is described in the box above the editor.
}

Running as a guest

The tests run right here, no account needed. Your code is kept in this browser only. A free account keeps it on every device, marks the step done and shows where you are in the course.

Hint ladder

Stuck? Reveal one rung at a time, but try it yourself first.

    We use necessary cookies to run the site (sign-in and language). If you accept, we also load Google Analytics to see which pages are used, and Google reCAPTCHA to keep spam off the contact and bug-report forms. Privacy policy