Home DSA Linear Search Algorithm Explained — How It Works, When to Use It, and Why It Matters

Linear Search Algorithm Explained — How It Works, When to Use It, and Why It Matters

In Plain English 🔥
Imagine you've got a messy drawer full of socks and you're looking for the one red sock. You don't magically know where it is, so you pick up the first sock, check if it's red, put it down if it's not, then pick up the next one — and so on until you find it. That's linear search. You check every single item, one at a time, in order, until you find what you're looking for (or run out of socks). No tricks, no shortcuts — just a straightforward, honest search from start to finish.
⚡ Quick Answer
Imagine you've got a messy drawer full of socks and you're looking for the one red sock. You don't magically know where it is, so you pick up the first sock, check if it's red, put it down if it's not, then pick up the next one — and so on until you find it. That's linear search. You check every single item, one at a time, in order, until you find what you're looking for (or run out of socks). No tricks, no shortcuts — just a straightforward, honest search from start to finish.

Every app you've ever used searches for something. Your music app searches for a song by name. Your contacts app finds a phone number. Your email client hunts for a message from last Tuesday. Under the hood, all of these rely on some form of search algorithm — a set of steps a computer follows to find a specific piece of data inside a collection. Without search algorithms, every piece of software that handles data would be helpless. Linear search is the most fundamental of them all, and understanding it is the foundation for understanding everything smarter that comes after it.

The problem linear search solves is deceptively simple: given a list of items, find whether a specific target item exists in that list, and if so, tell us exactly where it is. Sounds easy, right? But computers don't have eyes. They can't 'glance' at a list and spot something instantly. They need explicit instructions: start here, check this, move to the next one. Linear search gives them those exact instructions in the most straightforward way possible — check every element, one at a time, from the beginning to the end.

By the end of this article, you'll understand exactly how linear search works step by step, you'll be able to write a complete, working linear search function in Java from memory, you'll know its time and space complexity and what that means in plain English, and you'll know precisely when to reach for it — and when to put it down and use something better. You'll also walk away with the two gotchas that trip up almost every beginner, and the interview answers that will make you sound like you actually understand what's happening under the hood.

How Linear Search Actually Works — Step by Step

Let's make this concrete. Say you have an array of five student ID numbers: [1042, 3387, 2291, 4410, 1895]. You want to find whether ID number 4410 exists in that list.

Linear search does this: it starts at index 0 (the first position) and asks 'is this 4410?' The answer is no — it's 1042. So it moves to index 1 and asks the same question. No, that's 3387. Index 2? No, 2291. Index 3? Yes — 4410 matches! The algorithm stops and reports back: 'Found it at position 3.'

If the target wasn't in the list at all, the algorithm would keep going until it ran out of elements, then report 'not found.' That's it. No magic. No sorting required. No preprocessing. Just a simple, honest loop.

One thing that trips people up early: the algorithm stops as soon as it finds the first match. If your list has duplicates, linear search returns the index of the very first occurrence and doesn't keep looking. This is almost always the right behaviour, but it's worth knowing.

LinearSearchBasic.java · JAVA
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
public class LinearSearchBasic {

    /**
     * Searches for a target value inside an array of integers.
     *
     * @param numbers  The array we want to search through
     * @param target   The number we're looking for
     * @return         The index where the target was found, or -1 if it doesn't exist
     */
    public static int linearSearch(int[] numbers, int target) {

        // Start at the very first element (index 0) and walk forward one step at a time
        for (int index = 0; index < numbers.length; index++) {

            // Ask the key question: is THIS element the one we're looking for?
            if (numbers[index] == target) {
                // Yes! Stop immediately and report WHERE we found it
                return index;
            }
            // No match — the loop automatically moves to the next index
        }

        // If we reach here, we checked every single element and found nothing
        // Returning -1 is the universal convention for 'not found'
        return -1;
    }

    public static void main(String[] args) {

        int[] studentIds = {1042, 3387, 2291, 4410, 1895};
        int targetId = 4410;

        int resultIndex = linearSearch(studentIds, targetId);

        // -1 means the target was not found anywhere in the array
        if (resultIndex != -1) {
            System.out.println("Student ID " + targetId + " found at index " + resultIndex);
        } else {
            System.out.println("Student ID " + targetId + " does not exist in the list.");
        }

        // Now test the 'not found' case
        int missingId = 9999;
        int missingResult = linearSearch(studentIds, missingId);

        if (missingResult != -1) {
            System.out.println("Student ID " + missingId + " found at index " + missingResult);
        } else {
            System.out.println("Student ID " + missingId + " does not exist in the list.");
        }
    }
}
▶ Output
Student ID 4410 found at index 3
Student ID 9999 does not exist in the list.
🔥
Why -1 and not 0?Returning -1 for 'not found' is a convention used across almost every language and library (Java's String.indexOf(), Python's list.find(), etc.). You can't use 0 because 0 is a valid index — it means 'found at the very first position.' Negative numbers can never be valid array indices, so -1 is a safe, unambiguous sentinel value.

Every algorithm has a cost. That cost is measured in two ways: time (how many steps does it take?) and space (how much extra memory does it need?). Understanding this for linear search is crucial — not because it's hard, but because it's the baseline you'll compare every other search algorithm against for the rest of your career.

Time Complexity — the 'how long' question: In the best case, the target is the very first element. One comparison, done. That's O(1) — constant time. In the worst case, the target is the last element, or it's not in the list at all. You checked every single element — that's n comparisons for a list of n items. That's O(n) — linear time, which is where the algorithm gets its name. On average, you'll find the target somewhere in the middle, which is roughly n/2 comparisons — still O(n) because we drop constants in Big O notation.

Space Complexity — the 'how much memory' question: Linear search is O(1) space. It doesn't create any new arrays or data structures. It just uses a single loop variable (the index counter). No matter if your input has 10 items or 10 million, the extra memory used stays constant.

The honest takeaway: linear search is slow for large datasets but costs almost nothing in memory. It's the algorithm equivalent of a reliable old bicycle — not the fastest thing on the road, but it always gets you there and never breaks down.

LinearSearchComplexityDemo.java · JAVA
123456789101112131415161718192021222324252627282930313233343536373839404142
public class LinearSearchComplexityDemo {

    // We'll count comparisons manually so you can SEE the O(n) behaviour
    public static int linearSearchWithCount(int[] numbers, int target) {
        int comparisonCount = 0; // Track how many times we check an element

        for (int index = 0; index < numbers.length; index++) {
            comparisonCount++; // Every loop iteration is one comparison

            if (numbers[index] == target) {
                System.out.println("Found after " + comparisonCount + " comparison(s).");
                return index;
            }
        }

        System.out.println("Not found. Made " + comparisonCount + " comparison(s) — checked every element.");
        return -1;
    }

    public static void main(String[] args) {
        int[] temperatures = {72, 68, 91, 55, 83, 77, 64, 98, 45, 88};
        // Array has 10 elements (indices 0 through 9)

        System.out.println("--- Best Case: Target is the FIRST element ---");
        linearSearchWithCount(temperatures, 72); // At index 0

        System.out.println();

        System.out.println("--- Average Case: Target is somewhere in the MIDDLE ---");
        linearSearchWithCount(temperatures, 83); // At index 4

        System.out.println();

        System.out.println("--- Worst Case: Target is the LAST element ---");
        linearSearchWithCount(temperatures, 88); // At index 9

        System.out.println();

        System.out.println("--- Worst Case: Target does NOT exist ---");
        linearSearchWithCount(temperatures, 100); // Not in the array
    }
}
▶ Output
--- Best Case: Target is the FIRST element ---
Found after 1 comparison(s).

--- Average Case: Target is somewhere in the MIDDLE ---
Found after 5 comparison(s).

--- Worst Case: Target is the LAST element ---
Found after 10 comparison(s).

--- Worst Case: Target does NOT exist ---
Not found. Made 10 comparison(s) — checked every element.
⚠️
Interview Gold: Always state all three casesWhen an interviewer asks about complexity, don't just say 'O(n).' Say: 'Best case is O(1) if the target is the first element, worst case is O(n) if the target is last or absent, and average case is O(n). Space complexity is O(1) because no extra data structures are created.' This shows you actually understand the algorithm, not just memorised a label.

Linear Search on Strings and Custom Objects — It's Not Just for Numbers

Every example you see in textbooks uses integers. That's fine for learning, but real-world code searches through names, emails, product titles, and custom objects. Linear search works on all of these — the logic is identical. The only thing that changes is how you compare two elements.

With integers, you use ==. With Strings in Java, you must use .equals() — because == on objects checks whether two variables point to the same memory address, not whether they have the same content. This is one of the most common bugs beginners write, and it's the kind of bug that can pass your own manual tests but fail in production when the string comes from user input or a database.

With custom objects (like a Student class), you decide what 'equal' means. You might search by name, by ID, or by email. You write the comparison logic yourself. This makes linear search incredibly flexible — you can search any collection for any criteria without sorting or pre-processing anything first. That flexibility is genuinely valuable in small collections and quick scripts.

LinearSearchStringsAndObjects.java · JAVA
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
public class LinearSearchStringsAndObjects {

    // --- Searching through an array of Strings ---
    public static int searchByName(String[] names, String targetName) {
        for (int index = 0; index < names.length; index++) {
            // CRITICAL: Use .equals() for Strings, NOT ==
            // .equals() compares the actual text content character by character
            if (names[index].equals(targetName)) {
                return index;
            }
        }
        return -1; // Name not found
    }

    // --- A simple Student record to demonstrate searching objects ---
    static class Student {
        int studentId;
        String fullName;
        double gpa;

        Student(int studentId, String fullName, double gpa) {
            this.studentId = studentId;
            this.fullName = fullName;
            this.gpa = gpa;
        }
    }

    // --- Searching through an array of Student objects by their ID ---
    public static Student searchById(Student[] roster, int targetId) {
        for (int index = 0; index < roster.length; index++) {
            // We define what 'match' means: two students match if their IDs are equal
            if (roster[index].studentId == targetId) {
                return roster[index]; // Return the whole Student object, not just the index
            }
        }
        return null; // Convention: return null when a searched object isn't found
    }

    public static void main(String[] args) {

        // --- String search demo ---
        String[] cityNames = {"Austin", "Denver", "Phoenix", "Nashville", "Portland"};
        String searchCity = "Nashville";

        int cityIndex = searchByName(cityNames, searchCity);
        if (cityIndex != -1) {
            System.out.println(searchCity + " found at index " + cityIndex);
        } else {
            System.out.println(searchCity + " is not in the list.");
        }

        // --- Object search demo ---
        Student[] classRoster = {
            new Student(1001, "Maria Chen", 3.8),
            new Student(1042, "James Okafor", 3.5),
            new Student(1087, "Priya Nair", 3.9),
            new Student(1103, "Lucas Ferreira", 3.2)
        };

        int searchId = 1087;
        Student foundStudent = searchById(classRoster, searchId);

        if (foundStudent != null) {
            System.out.println("Found student: " + foundStudent.fullName
                + " | GPA: " + foundStudent.gpa);
        } else {
            System.out.println("No student with ID " + searchId + " found.");
        }
    }
}
▶ Output
Nashville found at index 3
Found student: Priya Nair | GPA: 3.9
⚠️
Watch Out: == vs .equals() on StringsUsing == to compare two String values in Java checks reference equality (do these two variables point to the same object in memory?), not value equality (do they contain the same text?). This bug is insidious because it sometimes works — when Java reuses a string from its internal pool — but silently fails when the string comes from a Scanner, database, or API. Always use .equals() or .equalsIgnoreCase() when comparing String content.

When to Use Linear Search — and When to Walk Away

Linear search isn't a bad algorithm. It's a misused one. Knowing when it's exactly the right tool is what separates a developer who memorised a concept from one who actually understands it.

Use linear search when: Your list is small (under a few hundred items) and performance isn't critical. Your data is unsorted and you can't afford the time to sort it first. You're searching based on a condition that can't be indexed, like 'find the first student with a GPA above 3.7' — you genuinely have to check each one. You're writing a quick script or throwaway tool and simplicity beats optimisation.

Don't use linear search when: Your dataset is large (thousands of records or more) and you're searching repeatedly. In that case, binary search (for sorted data) gives you O(log n) — searching a million items in about 20 steps instead of a million. Or use a HashMap for O(1) lookup by key. The performance difference becomes dramatic at scale.

The honest real-world truth: most production code that 'searches a list' is actually using a database index, a HashMap, or a sorted structure. But every single one of those was built by someone who first understood linear search. It's the bedrock.

LinearSearchRealWorldUse.java · JAVA
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
import java.util.ArrayList;
import java.util.List;

public class LinearSearchRealWorldUse {

    // Real-world use case: find all products under a given price threshold
    // This CAN'T use binary search because we want ALL matches, not just one,
    // and the condition is a range, not an exact value.
    // Linear search is genuinely the right tool here.

    static class Product {
        String name;
        double priceInDollars;
        boolean inStock;

        Product(String name, double priceInDollars, boolean inStock) {
            this.name = name;
            this.priceInDollars = priceInDollars;
            this.inStock = inStock;
        }
    }

    // Returns ALL in-stock products at or below the budget — not just the first one
    public static List<Product> findAffordableInStockProducts(
            Product[] catalogue, double budget) {

        List<Product> matches = new ArrayList<>();

        for (int index = 0; index < catalogue.length; index++) {
            // Two conditions must BOTH be true to add this product to results
            boolean withinBudget = catalogue[index].priceInDollars <= budget;
            boolean available = catalogue[index].inStock;

            if (withinBudget && available) {
                matches.add(catalogue[index]); // Collect the match; keep going
            }
            // Notice: we do NOT return early — we need to check every product
        }

        return matches; // Return everything we found
    }

    public static void main(String[] args) {
        Product[] storeCatalogue = {
            new Product("Wireless Earbuds",  79.99,  true),
            new Product("Laptop Stand",       45.00,  true),
            new Product("Mechanical Keyboard", 129.99, false), // Out of stock
            new Product("USB Hub",             35.50,  true),
            new Product("Webcam HD",           89.99,  true),
            new Product("Monitor Light",       49.99,  false) // Out of stock
        };

        double userBudget = 80.00;

        List<Product> recommendations =
            findAffordableInStockProducts(storeCatalogue, userBudget);

        System.out.println("In-stock products under $" + userBudget + ":");
        for (Product product : recommendations) {
            System.out.println("  - " + product.name
                + " ($" + product.priceInDollars + ")");
        }
    }
}
▶ Output
In-stock products under $80.0:
- Wireless Earbuds ($79.99)
- Laptop Stand ($45.0)
- USB Hub ($35.5)
⚠️
Pro Tip: Linear search shines with complex conditionsBinary search and hash maps are great for exact-match lookups on sorted or keyed data. But when your search condition is a combination of fields ('in stock AND under budget AND not discontinued'), linear search is often cleaner and simpler than trying to force that logic into a more complex data structure. Always match the tool to the problem, not your desire to show off.
Feature / AspectLinear SearchBinary Search
Requires sorted data?No — works on any arrayYes — data MUST be sorted first
Time complexity (worst)O(n) — checks every elementO(log n) — halves the search space each step
Time complexity (best)O(1) — target is first elementO(1) — target is middle element
Space complexityO(1) — no extra memory neededO(1) iterative / O(log n) recursive
Works on unsorted data?Yes, alwaysNo — gives wrong results on unsorted data
Works on linked lists?Yes — just traverse forwardNo — requires random index access
Implementation complexityVery simple — a single loopModerate — tricky boundary conditions
Best used whenSmall data, unsorted, complex conditionsLarge sorted data, repeated exact lookups
Can find ALL matches?Yes — just don't return earlyNot easily — finds one match near the middle

🎯 Key Takeaways

  • Linear search checks every element one by one from start to finish — it needs no sorting, no preprocessing, and no special data structure. That simplicity is a feature, not just a limitation.
  • Worst-case time complexity is O(n) — if the target is last or absent, you check every element. Best case is O(1). Space complexity is always O(1) because no extra memory is allocated regardless of input size.
  • Always use .equals() to compare Strings and always return -1 (not 0) for 'not found' — these two conventions prevent the two most common linear search bugs beginners write in Java.
  • Linear search is the right choice for small or unsorted data and for complex multi-condition searches. For large sorted datasets with repeated lookups, binary search (O(log n)) or a HashMap (O(1)) will dramatically outperform it.

⚠ Common Mistakes to Avoid

  • Mistake 1: Using == to compare Strings instead of .equals() — Symptom: your search returns -1 even when the target string is visually right there in the array. This happens because == compares memory addresses, not text content, and strings from user input or external sources live at different memory locations than your literal values. Fix: always use targetString.equals(arrayElement) for String comparisons, or equalsIgnoreCase() if casing might differ.
  • Mistake 2: Returning 0 instead of -1 for 'not found' — Symptom: calling code can't tell the difference between 'found at index 0' (the first element) and 'not found at all,' leading to the wrong element being returned to the user. Fix: use -1 as your sentinel value for 'not found' — it can never be a valid array index, so it's unambiguous. This is the universal convention across Java, Python, and JavaScript standard libraries.
  • Mistake 3: Forgetting to check the return value before using it — Symptom: a NullPointerException or ArrayIndexOutOfBoundsException crash at runtime when the search returns -1 and the calling code blindly uses it as an index (e.g., array[-1]). Fix: always check the result before acting on it — wrap your usage in an if (result != -1) block, or if searching objects, check if (foundObject != null) before accessing its fields.

Interview Questions on This Topic

  • QWhat is the time complexity of linear search in the best, average, and worst case — and can you explain what causes each case to occur?
  • QIf I have a sorted array of 10,000 integers and I need to search it thousands of times per second, would you use linear search? What would you use instead and why?
  • QHow would you modify a linear search function to return ALL indices where a target value appears, rather than just the first one? What change does this force you to make to the function's return type and early-exit logic?

Frequently Asked Questions

What is linear search and when should I use it?

Linear search is an algorithm that finds a target value in a list by checking each element one at a time from the beginning until it finds a match or runs out of elements. Use it when your data is unsorted, your list is small, or your search condition is too complex for indexed lookups — like finding all records that satisfy multiple field conditions simultaneously.

What is the time complexity of linear search?

Linear search has O(1) best-case time complexity (when the target is the very first element), O(n) worst-case complexity (when the target is last or doesn't exist), and O(n) average-case complexity. Its space complexity is always O(1) because it uses only a loop counter and no additional data structures.

Does linear search require the array to be sorted?

No — and that's one of its biggest advantages over binary search. Linear search works correctly on completely unsorted data because it doesn't make any assumptions about the order of elements. It simply checks each one in sequence. Binary search, by contrast, will give wrong results on unsorted data because its halving logic depends on the sorted order being intact.

🔥
TheCodeForge Editorial Team Verified Author

Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

← PreviousBinary Search on AnswerNext →Ternary Search Algorithm
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged