Binary Search on Sorted Data
Lesson 25Intermediate52 minAssessment-backed

Binary Search on Sorted Data

Shrink a sorted search interval with precise boundaries, loop invariants, duplicates, insertion points, and production-safe edge cases.

What you will be able to do

Explain binary search as safe interval elimination.
Implement exact lookup and lower-bound search.
Handle empty input, duplicates, and insertion points.
Avoid midpoint overflow and infinite-loop boundary bugs.
Connect binary search to sorted indexes and product lookup.

Binary search is not guessing the middle. It is a proof that half of the remaining search space cannot contain the answer. That proof depends on sorted data, a correct invariant, and careful boundary movement.

The Interval Invariant

At every step, binary search keeps an interval that may still contain the answer. Compare the middle value with the target, then discard the half that cannot contain a valid answer. If the boundaries do not shrink, the loop can run forever.

Binary search interval shrinking on sorted data
The power is not the middle element. The power is safely eliminating impossible positions.

SkillSkore principle

Use binary search only when the search space has monotonic structure: after a comparison, one side can be discarded without losing the answer.

Scenario: Finding an Event in a Sorted Log

A monitoring system stores event timestamps in ascending order. When an incident starts at 14:03, engineers need the first event at or after that time. Exact search is not enough; they need the lower bound insertion point.

NeedBinary-search variantWhy
Find exact valueExact lookupReturn index only when nums[mid] equals target.
First value >= targetLower boundUsed for timestamps, insertion points, and range starts.
First value > targetUpper boundUsed for duplicate ranges and exclusive boundaries.
Count duplicateslower + upper boundsAvoid scanning large duplicate regions.
Lower bound for first timestamp at or after target
Lower bound is often more useful than exact lookup in real systems.

Same Pattern in Java, Python, and JavaScript

Lower bound returns the first index whose value is greater than or equal to target. If every value is smaller, it returns nums.length.

class LowerBound {
    static int lowerBound(int[] nums, int target) {
        int left = 0;
        int right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        return left;
    }
}

Boundary Bugs Engineers Actually Make

  • Using `while (left <= right)` with lower-bound boundary updates from `while (left < right)`.
  • Setting `right = mid - 1` when the mid value could still be the first valid answer.
  • Computing mid as `(left + right) / 2` in languages where large integer addition can overflow.
  • Returning `mid` after the loop instead of the converged boundary.
  • Ignoring duplicate values when the prompt asks for first or last occurrence.

Assessment trap

Binary search answers are graded on the invariant. If you cannot say what the interval means, the code is probably memorized.

Interview signalFrequently Asked Interview Questions

These are canonical interview patterns for this topic, phrased as concrete problem statements. They avoid vague theory questions and prepare you for the exact reasoning interviewers expect: invariant, edge cases, complexity, and trade-off.

  • Return the index where target exists or should be inserted in sorted order.
  • Return the first and last index of target in a sorted array.
  • Find target in a rotated sorted array with distinct values.

Production practiceCompany-Style Practice Examples

These are not claimed as exact company-specific questions. They are the interview patterns repeatedly used by product companies to test whether you can move from brute force to a defensible implementation.

ExampleBrute-force approachStronger solutionProduction notes
First event after incident startScan timestamps from the beginning.Use lower bound on sorted timestamps.Returns insertion point even without exact match.
Duplicate target rangeBinary search one match, then scan outward.Use lower and upper bounds.Avoids large duplicate-region scans.
Search unsorted recordsApply binary search anyway.Sort/index first or use a different lookup structure.Binary search requires monotonic order.

Solved modelInterview Question Solutions

Question 1: Search Insert Position

Return the index where target exists or should be inserted in sorted order. This is lower bound: first value greater than or equal to target.

class LowerBoundAnswer {
    static int lowerBound(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        return left;
    }
}

Question 2: First and Last Position

Return the first and last index of target in a sorted array. Use lower_bound(target) and lower_bound(target + 1) or an upper-bound variant. Validate that the first bound actually equals target.

class SearchRange {
    static int[] range(int[] nums, int target) {
        int first = lower(nums, target);
        int after = lower(nums, target + 1);
        if (first == nums.length || nums[first] != target) return new int[]{-1, -1};
        return new int[]{first, after - 1};
    }
    static int lower(int[] nums, int target) { int l = 0, r = nums.length; while (l < r) { int m = l + (r - l) / 2; if (nums[m] < target) l = m + 1; else r = m; } return l; }
}

Question 3: Search Rotated Sorted Array

Find target in a rotated sorted array with distinct values. At each step, one half is sorted. Decide whether target lies inside that sorted half before discarding the other half.

class RotatedSearch { static int search(int[] nums, int target) { int l = 0, r = nums.length - 1; while (l <= r) { int m = l + (r - l) / 2; if (nums[m] == target) return m; if (nums[l] <= nums[m]) { if (nums[l] <= target && target < nums[m]) r = m - 1; else l = m + 1; } else { if (nums[m] < target && target <= nums[r]) l = m + 1; else r = m - 1; } } return -1; } }

Solved modelWorked Interview Answer

Return the first index whose value is greater than or equal to target. Lower bound keeps the first possible answer inside [left, right). When nums[mid] is already valid, move right to mid instead of discarding it.

class LowerBoundAnswer {
    static int lowerBound(int[] nums, int target) {
        int left = 0, right = nums.length;
        while (left < right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] < target) left = mid + 1;
            else right = mid;
        }
        return left;
    }
}

Hands-on drillTry It Yourself

Practice task

For [1, 2, 2, 2, 5, 7] and target 2, trace lower_bound and upper_bound. Record left, right, mid, and the invariant each iteration.

Failure patternsCommon Mistakes to Avoid

  • Mixing inclusive and exclusive boundary templates.
  • Moving right past a possible answer in lower bound.
  • Returning mid after the loop.
  • Ignoring duplicates when first occurrence is required.
  • Not proving sorted or monotonic structure.

Execution guardrailQuick-Start Checklist

  • Define the invariant.
  • Choose inclusive or half-open interval.
  • Compute mid safely.
  • Move boundaries so the interval shrinks.
  • Return the converged boundary.
  • Test empty, one item, no match, and duplicate cases.

Recall drillKnowledge Check

QuestionStrong answer
What does lower bound return?The first index whose value is greater than or equal to target.
Why use right = mid in lower bound?mid may be the first valid answer, so it must remain in the interval.
What makes binary search valid?A sorted or monotonic property that lets one side be safely discarded.

VocabularyKey Terms

TermMeaning
Lower boundFirst position where value is >= target.
Upper boundFirst position where value is > target.
InvariantThe meaning preserved by the search interval.
Half-open intervalAn interval like [left, right) where right is excluded.

Next practiceFurther Reading

  • Practice search insert position, first/last occurrence, and rotated sorted array later.
  • Review database B-tree indexes conceptually.
  • Compare binary search templates before memorizing code.