const solve = (nums) => { let left = 0, right = nums.length - 1; while (left < right) { const sum = nums[left] + nums[right]; if (sum === target) return [left, right]; }}
Problem Walkthrough

Binary Search LeetCode 704: The Template Every Variant Builds On

Master the purest binary search implementation and unlock every variation of the algorithm.

6 min read|

Binary Search (#704): the template every variant builds on

Left, right, mid — the purest binary search implementation

Understanding the Problem — Binary Search Explained

The problem statement is refreshingly short. You are given a sorted array of integers nums and a target value. Return the index of the target if it exists, or -1 if it does not. The constraint: your solution must run in O(log n) time.

That O(log n) requirement is the key. A simple for-loop scan would work in O(n), but the problem explicitly forbids it. You need to cut the search space in half on every step — and that is exactly what binary search does.

Because the array is sorted, you can compare the middle element to your target and immediately discard half the remaining elements. This halving is what gives binary search its logarithmic time complexity. For an array of one million elements, you need at most 20 comparisons instead of one million.

ℹ️

Did You Know

Binary Search (#704) is the most solved Easy binary search problem — it teaches the exact template used in Search Insert Position (#35), Find Minimum Rotated (#153), and every binary search variant.

The Binary Search Template — Left, Right, Mid

Here is the binary search template in its purest form. Every binary search variant starts from these exact lines and adds one modification. Memorize this pattern and you have the foundation for every binary search problem on LeetCode.

Initialize two pointers: left = 0 and right = len(nums) - 1. These define the current search space — every element between left and right (inclusive) is still a candidate. Then enter the loop: while left <= right, compute mid = left + (right - left) // 2.

Now compare nums[mid] to the target. If they are equal, you found the answer — return mid. If the target is greater than nums[mid], the answer must be to the right, so set left = mid + 1. If the target is smaller, set right = mid - 1. When the loop ends without finding the target, return -1.

  • left = 0, right = len(nums) - 1 — search the entire array
  • while left <= right — keep searching while the window is valid
  • mid = left + (right - left) // 2 — overflow-safe midpoint
  • nums[mid] == target — found it, return mid
  • target > nums[mid] — discard left half, set left = mid + 1
  • target < nums[mid] — discard right half, set right = mid - 1
  • Loop exits without match — return -1

Why left <= right, Not left < right

This single character — the equals sign in <= — is the most common source of binary search bugs. Understanding why it matters will save you from subtle off-by-one errors in every binary search problem you tackle.

The loop condition left <= right means the search space can narrow all the way down to a single element (where left == right) and still be checked. If you use left < right instead, the loop exits when left equals right, and that last remaining element is never examined.

Imagine searching for 9 in the array [-1, 0, 3, 5, 9, 12]. In the final iteration, both left and right point to index 4 (the element 9). With left <= right, you enter the loop, check nums[4], find the target, and return 4. With left < right, the loop skips this iteration entirely and incorrectly returns -1.

The rule is simple: when your search space is [left, right] inclusive and you shrink it with mid + 1 and mid - 1, always use left <= right. This is the standard binary search template and the correct choice for LeetCode 704.

⚠️

Common Bug

The most common binary search bug is using left < right instead of left <= right — this misses the case where the search space is a single element. Always use <= for standard binary search.

Visual Walkthrough — Searching for 9 in [-1,0,3,5,9,12]

Let us trace the binary search template step by step on the array [-1, 0, 3, 5, 9, 12] with a target of 9. This is the binary search left right mid pattern in action.

Step 1: left = 0, right = 5. mid = (0 + 5) // 2 = 2. nums[2] = 3. Since 9 > 3, set left = mid + 1 = 3. The search space shrinks to [3, 5, 9, 12].

Step 2: left = 3, right = 5. mid = (3 + 5) // 2 = 4. nums[4] = 9. Since 9 == 9, return 4. Done in just two iterations.

Now consider searching for 2 in the same array. Step 1: left = 0, right = 5, mid = 2, nums[2] = 3. Since 2 < 3, set right = mid - 1 = 1. Step 2: left = 0, right = 1, mid = 0, nums[0] = -1. Since 2 > -1, set left = 1. Step 3: left = 1, right = 1, mid = 1, nums[1] = 0. Since 2 > 0, set left = 2. Now left > right, so the loop exits and we return -1.

  1. 1Initialize left = 0 and right = length - 1 to cover the full array
  2. 2Compute mid = left + (right - left) // 2 to find the center
  3. 3Compare nums[mid] with target — equal means found, greater means go right, less means go left
  4. 4Update left or right to shrink the search space by half
  5. 5Repeat until left > right — if the loop ends, the target is not in the array

Edge Cases Every Binary Search Beginner Should Know

The template handles the happy path, but interviews love edge cases. Here are the scenarios you should test mentally before submitting any binary search solution.

Empty array: If nums has length 0, left starts at 0 and right starts at -1. The condition left <= right is false immediately, so the loop never executes and you return -1. No special case needed — the template handles it.

Single element: If nums has one element, left and right both equal 0. You compute mid = 0 and check nums[0]. If it matches, return 0. If not, you adjust left or right so the loop exits next iteration. Again, the template covers this naturally because of the <= condition.

Target at boundaries: When the target is the first or last element, binary search still converges. It may take log(n) steps to reach the boundary, but the narrowing logic always gets there. Test with target = nums[0] and target = nums[n-1] to build confidence.

  • Empty array — returns -1 immediately, no special handling
  • Single element — checked in one iteration thanks to left <= right
  • Target is first element — converges by shrinking right repeatedly
  • Target is last element — converges by shrinking left repeatedly
  • Target not in array — loop exhausts search space, returns -1
💡

Pro Tip

Use mid = left + (right - left) // 2 instead of (left + right) // 2 — this prevents integer overflow when left + right exceeds the integer max. Same result, safer code.

What Binary Search #704 Teaches You

LeetCode 704 is not just a problem — it is a foundation. The binary search template you learned here is the exact skeleton used in Search Insert Position (#35), where you return the insertion index instead of -1. It is the same skeleton in Find Peak Element (#162), where the comparison changes from target vs. mid to mid vs. mid+1.

Every binary search variant modifies exactly one piece of this template: the comparison logic, the return value, or the search space boundaries. Once the basic pattern is in your muscle memory, learning each variant becomes a matter of identifying which piece changes.

Practice this template until you can write it without thinking. Then move on to the variants — rotated arrays, peak finding, search ranges — and notice how each one is just #704 with a twist. YeetCode flashcards can help you drill the pattern with spaced repetition so it sticks for interview day.

Ready to master algorithm patterns?

YeetCode flashcards help you build pattern recognition through active recall and spaced repetition.

Start practicing now