BackendBench
Coffee

Unravel โ€บ Java concepts โ€บ Algorithms and data structures

Java language

Binary search

Binary search finds a value in a sorted array by repeatedly comparing with the middle element and discarding the half that cannot contain it.

Learn these first

At a glance

Mental model

Guess my number between 1 and 100: always guess the middle and I answer "higher" or "lower".

What happens, in order
  1. 1Keep two bounds lo and hiWhile lo <= hi: mid = lo + (hi - lo) / 2; if a[mid] == target return it; if it is smaller, lo = mid + 1; otherwise hi = mid - 1. If the loop ends, the value is absent.
  2. 2The standard library does it for you: Arrays.binarySearch(a, key) and Collections.binarySearch(list, key)A negative result -(insertionPoint) - 1 means "not found, would go here".
  3. 3The data must be sorted by the same orderingThe idea also works on any monotonic condition ("smallest x such that f(x) is true"): shipping capacity, square roots, first bad version.
Remember
Watch out
Searching an unsorted arrayInfinite loop from lo = mid instead of mid + 1Overflow in (lo + hi) / 2Misreading the negative return value
Example (highlighted lines explain it)
public class Search {  static int indexOf(int[] sorted, int target) {    int lo = 0, hi = sorted.length - 1;    while (lo <= hi) {      int mid = lo + (hi - lo) / 2;      if (sorted[mid] == target) return mid;      if (sorted[mid] < target) lo = mid + 1;      else hi = mid - 1;    }    return -1;  }  static int builtIn(int[] sorted, int target) { return java.util.Arrays.binarySearch(sorted, target); }}
  1. line 12 uses binarySearch, the core of Binary search
Read the full explanation (about 2 min)

Binary search finds a value in a sorted array by repeatedly comparing with the middle element and discarding the half that cannot contain it. It needs about log2(n) steps: 20 comparisons for a million items.

A mental model

Guess my number between 1 and 100: always guess the middle and I answer "higher" or "lower". Seven guesses are enough.

How it works

Keep two bounds lo and hi. While lo <= hi: mid = lo + (hi - lo) / 2; if a[mid] == target return it; if it is smaller, lo = mid + 1; otherwise hi = mid - 1. If the loop ends, the value is absent.

The standard library does it for you: Arrays.binarySearch(a, key) and Collections.binarySearch(list, key). A negative result -(insertionPoint) - 1 means "not found, would go here".

The data must be sorted by the same ordering. The idea also works on any monotonic condition ("smallest x such that f(x) is true"): shipping capacity, square roots, first bad version.

Going deeper

Off-by-one errors are the main risk: decide whether hi is inclusive or exclusive and keep it consistent in the loop condition and updates. Test with empty, one element, two elements, first, last and missing.

Compute the middle as lo + (hi - lo) / 2 or (lo + hi) >>> 1: (lo + hi) / 2 overflows for large indexes (a bug that lived in the JDK for nine years).

With duplicates, a plain search returns any matching position; for the first or last occurrence continue narrowing after a hit.

On a LinkedList binary search is O(n) because reaching the middle costs a walk. Use ArrayList or an array.

Under the hood

Each iteration halves the search interval, so n elements need at most floor(log2 n) + 1 comparisons. Arrays.binarySearch is exactly this loop over the array, with a comparator variant for objects.

Common mistakes

  • Searching an unsorted array.
  • Infinite loop from lo = mid instead of mid + 1.
  • Overflow in (lo + hi) / 2.
  • Misreading the negative return value.

How Unravel recognises it

When you paste code, Unravel looks for these signs of binary search. Spotting them yourself is a good habit when you read unfamiliar code:

Part of a learning path

Related concepts

Frequently asked questions

What is Binary search?

Binary search finds a value in a sorted array by repeatedly comparing with the middle element and discarding the half that cannot contain it. It needs about log2(n) steps: 20 comparisons for a million items.

What are the most common mistakes with Binary search?

Searching an unsorted array. Infinite loop from lo = mid instead of mid + 1. Overflow in (lo + hi) / 2. Misreading the negative return value.

How can I see Binary search in real code?

Paste your own Java into Unravel and it will point out where binary search appears, explain how it works at the detail level you choose, and draw the flow of the code around it.