Menu

Binary Search Pattern

Relevant source files

Purpose and Scope

This page documents the binary search pattern as implemented throughout the LeetCode problem solutions in the repository. Binary search is a fundamental algorithm pattern used to efficiently find elements or determine optimal values in sorted or monotonic search spaces with $O(\log n)$ time complexity.

This documentation covers:

  • Basic boundary search templates for finding left and right positions
  • Binary search on answer pattern for optimization problems
  • Implementation variations across 12+ programming languages
  • Common applications including range finding, insertion positions, and condition-based searches

For foundational binary search algorithm implementations and templates, see Binary Search Templates. For other algorithmic patterns like hash tables and sliding windows, see Hash Table Pattern and Sliding Window Pattern.


Binary Search Fundamentals

The repository documents binary search as finding boundaries rather than just searching sorted arrays. As stated in basic/searching/BinarySearch/README.md1-3: "二分的本质并非'单调性',而是'边界',只要找到某种性质,使得整个区间一分为二,那么就可以用二分把边界点二分出来" (The essence of binary search is not "monotonicity" but "boundary" - as long as you find a property that divides the entire interval in two, you can use binary search to find the boundary point).

Two Template Patterns

The codebase provides two standard templates that maintain the answer within the binary search interval:

Template 1: Finding Left Boundary

Diagram: Template 1 Pattern Flow

Sources: basic/searching/BinarySearch/README.md8-24

Template 2: Finding Right Boundary

Used when the condition requires left = mid (see basic/searching/BinarySearch/README.md26-43):

Key Differences:

AspectTemplate 1Template 2
Mid calculation(left + right) >> 1(left + right + 1) >> 1
On check trueright = midleft = mid
On check falseleft = mid + 1right = mid - 1
Use caseFind first position where condition is trueFind last position where condition is true

Sources: basic/searching/BinarySearch/README.md8-54


Problem Implementations

Template Mapping to Problem Solutions

Diagram: Binary Search Template Usage Across Problems

Sources: basic/searching/BinarySearch/README.md8-54 solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java81-102 solution/0000-0099/0035.Search Insert Position/Solution.java89-101 solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java140-148

Example: Problem 35 - Search Insert Position

The searchInsert() implementation in solution/0000-0099/0035.Search Insert Position/Solution.java89-101 follows Template 1:

Execution trace for nums = [1,3,5,6], target = 2:

Iterationlrmidnums[mid]ComparisonAction
Initial04----
104255 ≥ 2r = 2
202133 ≥ 2r = 1
301011 < 2l = 1
End11--l ≥ rreturn 1

Sources: solution/0000-0099/0035.Search Insert Position/README.md74-85 solution/0000-0099/0035.Search Insert Position/Solution.java89-101

Example: Problem 34 - Finding Range Boundaries

The searchRange() function in solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java85-89 calls a search() helper twice:

Diagram: Double Binary Search Strategy in searchRange()

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java85-102

The search() helper implementation:

Key insight: search(target + 1) returns the first position where nums[mid] >= target + 1, which is one past the last occurrence of target.

Cross-Language Implementation Comparison:

LanguageFunctionFile Reference
Pythonbisect_left()solution/0000-0099/0034.../Solution.py3-5
Javasearch() helpersolution/0000-0099/0034.../Solution.java91-101
C++lower_bound()solution/0000-0099/0034.../Solution.cpp4-5
Gosort.SearchInts()solution/0000-0099/0034.../Solution.go2-3
Rustsearch closuresolution/0000-0099/0034.../Solution.rs4-16
TypeScriptsearch() functionsolution/0000-0099/0034.../Solution.ts2-12

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md63-78 solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java85-102


Binary Search on Answer Pattern

A powerful variation is binary search on answer, used when finding the minimum or maximum value that satisfies certain conditions. The pattern exploits monotonicity: if value v satisfies the condition, all values > v (for minimum problems) or < v (for maximum problems) also satisfy it.

Pattern Components

Diagram: Binary Search on Answer Component Architecture

Sources: basic/searching/BinarySearch/README.md45-54 solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md84-96

Example: Problem 1870 - Minimum Speed to Arrive on Time

The minSpeedOnTime() function in solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java123-137 demonstrates binary search on answer using Template 1.

Code Structure Mapping:

The check() validation function at solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java140-148:

Diagram: minSpeedOnTime() Function Call Flow

Sources: solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md84-96 solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java123-148

Template Selection Guide

The key decision is choosing between Template 1 and Template 2 based on the update direction:

Template Selection Rules (from basic/searching/BinarySearch/README.md45-54):

  1. Write loop condition: while (left < right)
  2. Write mid calculation: mid = (left + right) / 2
  3. Determine which template based on the desired update:
    • If using right = mid, use Template 1 (no modification to mid)
    • If using left = mid, use Template 2 (add +1 to mid calculation)

Comparison Table:

Problem TypeTemplateMid CalculationCheck Success ActionExample
Find first valid positionTemplate 1(l + r) >> 1r = midProblem 34, 35
Find last valid positionTemplate 2(l + r + 1) >> 1l = midMaximum problems
Find minimum valueTemplate 1(l + r) >> 1r = midProblem 1870
Find maximum valueTemplate 2(l + r + 1) >> 1l = midProblem 1898

Why Template 2 needs +1:

When left = mid is used, without the +1, the following scenario causes infinite loop:

  • left = 1, right = 2
  • mid = (1 + 2) / 2 = 1
  • If check succeeds: left = mid = 1 → No progress!

With +1:

  • mid = (1 + 2 + 1) / 2 = 2
  • If check succeeds: left = 2 → Loop exits

Sources: basic/searching/BinarySearch/README.md45-54


Language-Specific Implementations

Standard Library Functions vs Manual Implementation

Diagram: Binary Search Implementation Strategies by Language

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/ solution/0000-0099/0035.Search Insert Position/

Built-in Function Reference

LanguageFunctionReturn ValueFile Example
Pythonbisect_left(a, x)Index of leftmost position to insert xsolution/0000-0099/0034.../Solution.py3
C++lower_bound(begin, end, val)Iterator to first element ≥ valsolution/0000-0099/0034.../Solution.cpp4
Gosort.SearchInts(a, x)Smallest index i with a[i] ≥ xsolution/0000-0099/0034.../Solution.go2
JavaArrays.binarySearch(a, key)Index if found, else -(insertion point)-1solution/0000-0099/0035.../Solution.java254-256

Manual Implementation Examples

Java - Explicit Helper Method:

From solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java91-101:

TypeScript - Inline Function:

From solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.ts2-12:

Rust - Closure with Type Inference:

From solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.rs4-16:

Go - Function Literal:

From solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go7-19:

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.java91-101 solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.ts2-12 solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/Solution.rs4-16 solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.go7-19


Implementation Decision Tree

Choosing the right binary search approach depends on the problem characteristics:

Problem Classification Examples:

ProblemTypePattern UsedKey Feature
Problem 34Boundary SearchDouble binary searchFinds both left and right
Problem 35Insertion PositionLeft boundaryStandard lower_bound
Problem 1870OptimizationBinary search on answer (min)Check function validates speed
Problem 1898OptimizationBinary search on answer (max)Subsequence validation check

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md solution/0000-0099/0035.Search Insert Position/README.md solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md solution/1800-1899/1898.Maximum Number of Removable Characters/README.md


Implementation Best Practices

Half-Open Interval Pattern

All implementations use <FileRef file-url="https://github.com/doocs/leetcode/blob/86225ea1/left, right) where right is exclusive#LNaN-LNaN" NaN file-path="left, right)whereright` is exclusive">Hii

Mid Calculation: Bit Shift Operations

Java example from solution/0000-0099/0035.Search Insert Position/Solution.java94:

Why bit shift?

  • >>> 1 is equivalent to / 2 but faster
  • Avoids overflow: (left + right) might overflow, but shift handles it
  • Alternative: left + (right - left) / 2 (explicitly overflow-safe)

Sources: solution/0000-0099/0035.Search Insert Position/Solution.java94 solution/0000-0099/0035.Search Insert Position/Solution.cpp6

Early Exit Optimization

From solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java124-126:

Pattern: Validate problem constraints before entering binary search loop. For Problem 1870, if there are more trains than ceiling of available hours, it's impossible to complete the journey.

Sources: solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java124-126

Search Space Boundaries

From solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java129-130:

Key points:

  • Lower bound: 1 (minimum valid speed)
  • Upper bound: 10^7 + 1 (problem constraint + 1 for half-open interval)
  • Final validation: return l > m ? -1 : l; checks if answer exceeds constraint

Sources: solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java129-137

Check Function Requirements

The check() function in binary search on answer must satisfy:

Properties Table:

PropertyDescriptionExample from Problem 1870
DeterministicSame input → same outputcheck(dist, v, hour) always returns same boolean for same parameters
MonotonicIf check(x) true, then check(x+k) true (or opposite for max)If speed v works, speed v+1 also works
EfficientO(n) or betterIterate once through dist array
Correct boundaryReturns exactly the desired conditions <= hour matches "arrive on time"

Implementation from solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java140-148:

Sources: solution/1800-1899/1870.Minimum Speed to Arrive on Time/Solution.java140-148


Complexity Analysis

Time Complexity

PatternComplexityExplanation
Basic binary search$O(\log n)$Halves search space each iteration
Range search (both boundaries)$O(\log n)$Two independent binary searches
Binary search on answer$O(n \times \log m)$$\log m$ iterations, each with $O(n)$ check

Where:

  • $n$ = array length or problem size
  • $m$ = size of answer search space

Space Complexity

All implementations use $O(1)$ auxiliary space:

  • Only maintain left, right, and mid pointers
  • Check functions may use $O(n)$ for marking arrays (Problem 1898)

Example from Problem 1898:

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md67 solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md96 solution/1800-1899/1898.Maximum Number of Removable Characters/README.md89


Code Organization

Binary search solutions follow a consistent file structure:

solution/
├── 0000-0099/
│   ├── 0034.Find First and Last Position of Element in Sorted Array/
│   │   ├── README.md              # Chinese documentation
│   │   ├── README_EN.md           # English documentation
│   │   ├── Solution.py            # Python implementation
│   │   ├── Solution.java          # Java implementation
│   │   ├── Solution.cpp           # C++ implementation
│   │   ├── Solution.go            # Go implementation
│   │   ├── Solution.ts            # TypeScript implementation
│   │   ├── Solution.rs            # Rust implementation
│   │   ├── Solution.js            # JavaScript implementation
│   │   └── ...                    # Other language implementations
│   └── 0035.Search Insert Position/
│       └── [same structure]
└── 1800-1899/
    ├── 1870.Minimum Speed to Arrive on Time/
    │   └── [same structure]
    └── 1898.Maximum Number of Removable Characters/
        └── [same structure]

Documentation Structure:

  • Front matter with tags (二分查找, 数组) and difficulty
  • Problem description with constraints
  • Solution explanation with complexity analysis
  • Tabbed code examples in 6-12 languages

Sources: solution/0000-0099/0034.Find First and Last Position of Element in Sorted Array/README.md1-8 solution/1800-1899/1870.Minimum Speed to Arrive on Time/README.md1-11