Binary search is one of the most fundamental and powerful algorithms in computer science. Despite its apparent simplicity, mastering binary search requires understanding subtle boundary conditions, recognizing when to apply it, and knowing which template to use for different problem types. This algorithm appears in countless real-world systems, from database indexing to version control systems, and mastering it is essential for any serious programmer. This article provides a comprehensive guide to binary search, covering everything from basic concepts to advanced applications in LeetCode problems, along with practical insights into how this elegant algorithm powers modern computing systems.
Introduction
Binary search is a divide-and-conquer algorithm that efficiently locates a target value in a sorted array by repeatedly dividing the search space in half. The key insight is that if we compare the target with the middle element, we can eliminate half of the remaining elements in each iteration.
The algorithm's elegance lies in its logarithmic time complexity:
while linear search takes
Fundamentals
Core Concept
Binary search works on the principle of elimination: at each step, we compare the target with the middle element and eliminate half of the search space.
Visualization: 1
2
3
4
5
6
7Initial array: [1, 3, 5, 7, 9, 11, 13, 15]
Target: 7
Step 1: Compare with middle (index 3, value 7)
[1, 3, 5, 7, 9, 11, 13, 15]
↑
7 == 7 → Found!
Key Requirements: 1. Sorted array:
The array must be sorted (ascending or descending) 2. Comparable
elements: Elements must support comparison operations 3.
Random access: We need
Time and Space Complexity
Time Complexity:
- Best case:
- target is at the middle - Average case:
- typical search - Worst case:
- target at the end or not present
Space Complexity:
- Iterative:
- only a few variables - Recursive:
- recursion stack depth
Why
Each iteration eliminates half the elements. Starting with
- After 1 iteration:
elements remain - After 2 iterations:
elements remain - After
iterations: elements remain
We stop when
Basic Binary Search Template
The most straightforward binary search finds an exact match in a sorted array.
Standard Implementation
1 | def binary_search(nums, target): |
Key Points: 1. Loop condition:
left <= right ensures we check all valid positions 2.
Mid calculation:
left + (right - left) // 2 prevents integer overflow 3.
Boundary updates: mid + 1 and
mid - 1 exclude the current mid
Why
left + (right - left) // 2?
Using (left + right) // 2 can cause integer overflow
when left and right are large:
- If
left = 2^31 - 1andright = 2^31 - 1, thenleft + rightexceedsINT_MAX left + (right - left) // 2is mathematically equivalent but avoids overflow
Example Walkthrough
Problem: Find 7 in
[1, 3, 5, 7, 9, 11, 13, 15]
trace through this step by step. We start with the entire array as
our search space, with left=0 pointing to the first element
and right=7 pointing to the last element. The array has 8
elements, so our initial search space contains indices 0 through 7. In
the first iteration, we calculate
mid = 0 + (7 - 0) // 2 = 3, which gives us the middle
element. We compare nums[3] = 7 with our target value 7,
and they match perfectly. Since we found an exact match, we immediately
return index 3. This demonstrates the best-case scenario where binary
search finds the target in constant time.
1 | Initial: left=0, right=7 |
Problem: Find 6 in
[1, 3, 5, 7, 9, 11, 13, 15]
This example demonstrates a more typical case where the target
doesn't exist in the array. We start with the same initial boundaries.
In the first iteration, mid=3 gives us
nums[3]=7, which is greater than our target 6. Since the
array is sorted in ascending order, we know that all elements to the
right of index 3 (values 7, 9, 11, 13, 15) are also greater than 6, so
we can safely eliminate the entire right half. We update
right = mid - 1 = 2, effectively reducing our search space
to indices 0 through 2.
In the second iteration, we calculate
mid = 0 + (2 - 0) // 2 = 1, giving us
nums[1]=3. This value is less than our target 6, so we
eliminate the left half (indices 0 and 1) and update
left = mid + 1 = 2. Now our search space contains only
index 2.
In the third iteration, mid=2 gives us
nums[2]=5, which is still less than 6. We update
left = mid + 1 = 3. At this point, left=3 and
right=2, which means left > right,
violating our loop condition. This indicates that we've exhausted all
possible positions where the target could exist, so we exit the loop and
return -1 to indicate the target was not found.
1 | Initial: left=0, right=7 |
This walkthrough illustrates how binary search systematically narrows down the search space, eliminating half of the remaining possibilities at each step until either the target is found or we've confirmed it doesn't exist.
Boundary Handling: Left and Right Bound Templates
Many LeetCode problems require finding the first or last occurrence of a target, or the insertion position. These require modified templates.
Left Bound Template (First Occurrence)
Finds the leftmost position where target appears, or where it should be inserted.
1 | def left_bound(nums, target): |
Key Differences: 1. Right boundary:
right = len(nums) instead of len(nums) - 1 2.
Loop condition: left < right instead of
left <= right 3. Right update:
right = mid instead of right = mid - 1 4.
Return value: Returns left, which is the
insertion position
Why these changes?
right = len(nums)allows returning insertion position beyond arrayleft < rightensures we don't miss the boundary caseright = midkeeps mid in search space (it might be the answer)
Right Bound Template (Last Occurrence)
Finds the rightmost position where target appears.
1 | def right_bound(nums, target): |
Key Points:
- When
nums[mid] == target, we continue searching right (left = mid + 1) - After loop,
leftpoints to the position after the last occurrence - Return
left - 1if target exists,-1otherwise
Visual Comparison
Finding target = 5 in
[1, 3, 5, 5, 5, 7, 9]:
1 | Left Bound: |
Classic LeetCode Problems
LeetCode 704: Binary Search
Problem Statement: Given an array of integers
nums which is sorted in ascending order, and an integer
target, write a function to search target in
nums. If target exists, then return its index.
Otherwise, return -1.

Solution:
1 | class Solution: |
Edge Cases:
- Empty array:
[]→ Returns-1 - Single element:
[5], target5→ Returns0 - Target not present:
[1, 2, 3], target4→ Returns-1 - Target at boundaries:
[1, 2, 3], target1or3→ Returns0or2
Time Complexity:
LeetCode 35: Search Insert Position
Problem Statement: Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
Solution:
1 | class Solution: |
Example: 1
2
3
4
5
6
7
8nums = [1, 3, 5, 6], target = 5
→ Returns 2 (found at index 2)
nums = [1, 3, 5, 6], target = 2
→ Returns 1 (should be inserted at index 1)
nums = [1, 3, 5, 6], target = 7
→ Returns 4 (should be inserted at end)
Detailed Walkthrough for target = 2:
trace through the case where the target doesn't exist and we need to
find the insertion position. We initialize left=0 and
right=4 (note that right = len(nums), not
len(nums) - 1, because we need to handle the case where the
target should be inserted at the end).
In iteration 1, mid = 0 + (4 - 0) // 2 = 2. We compare
nums[2]=5 with target 2. Since
5 >= 2, we set right = mid = 2 to search
for the leftmost insertion position.
In iteration 2, left=0 and right=2, so
mid = 0 + (2 - 0) // 2 = 1. We compare
nums[1]=3 with target 2. Since
3 >= 2, we set right = mid = 1.
In iteration 3, left=0 and right=1, so
mid = 0 + (1 - 0) // 2 = 0. We compare
nums[0]=1 with target 2. Since
1 < 2, we set left = mid + 1 = 1.
Now left=1 equals right=1, so we exit the
loop. The function returns left=1, which is indeed the
correct insertion position: if we insert 2 at index 1, the array becomes
[1, 2, 3, 5, 6], maintaining sorted order.
Key Insight: This is exactly the left bound template! The insertion position is the leftmost position where we could place the target. The template naturally handles all cases: when the target exists, it returns the first occurrence; when it doesn't exist, it returns where it should be inserted to maintain sorted order.
Time Complexity:
LeetCode 34: Find First and Last Position
Problem Statement: Given an array of integers
nums sorted in non-decreasing order, find the starting and
ending position of a given target value. If
target is not found, return [-1, -1].
Solution:
1 | class Solution: |
Walkthrough for nums = [5, 7, 7, 8, 8, 10],
target = 8:
This problem requires finding both the first and last occurrence of the target value 8 in an array that contains duplicates. The key insight is that we need to use two different binary search strategies: one to find the leftmost occurrence and another to find the rightmost occurrence.
Finding the Left Bound (First Occurrence):
We initialize left=0 and right=6 (note that
right = len(nums), not len(nums) - 1, because
we're using the left-bound template). Our goal is to find the leftmost
position where we could insert the target value 8, which will be the
first occurrence if it exists.
In iteration 1, we calculate mid = 0 + (6 - 0) // 2 = 3.
However, wait — let me recalculate:
mid = 0 + (6 - 0) // 2 = 3. Actually, let's trace more
carefully. With left=0 and right=6,
mid = 0 + (6 - 0) // 2 = 3. We check
nums[3]=8, which equals our target. In the left-bound
template, when nums[mid] >= target, we set
right = mid to continue searching left, because
mid itself might be the leftmost occurrence. So
right=3.
In iteration 2, left=0 and right=3, so
mid = 0 + (3 - 0) // 2 = 1. We check
nums[1]=7, which is less than 8. Since we're looking for
the leftmost position where the value is at least 8, we know everything
to the left of index 1 is too small. We update
left = mid + 1 = 2.
In iteration 3, left=2 and right=3, so
mid = 2 + (3 - 2) // 2 = 2. We check
nums[2]=7, which is still less than 8. We update
left = mid + 1 = 3.
Now left=3 equals right=3, so we exit the
loop. The left bound is 3, meaning the first occurrence of 8 is at index
3.
1 | Left Bound: |
Finding the Right Bound (Last Occurrence):
For the right bound, we want to find the rightmost occurrence. We use
a different strategy: when nums[mid] <= target, we
continue searching right by setting left = mid + 1, because
we want to find the last occurrence.
In iteration 1, left=0 and right=6,
mid=3. nums[3]=8 <= 8, so we set
left = mid + 1 = 4 to continue searching right.
In iteration 2, left=4 and right=6,
mid=5. nums[5]=10 > 8, so we set
right=5 to search left.
In iteration 3, left=4 and right=5,
mid=4. nums[4]=8 <= 8, so we set
left = mid + 1 = 5.
Now left=5 equals right=5, so we exit. The
right bound algorithm returns left - 1 = 4, which is the
last occurrence of 8.
1 | Right Bound: |
Result: [3, 4]
After finding both bounds, we verify that the target exists by
checking if nums[left_idx] == target. Since
nums[3] == 8, we confirm the target exists and return
[3, 4] as the range of occurrences.
Time Complexity:
LeetCode 33: Search in Rotated Sorted Array
Problem Statement: There is an integer array
nums sorted in ascending order (with distinct values).
Prior to being passed to your function, nums is rotated at
an unknown pivot index. Given the target value, return the index of
target in nums, or -1 if it is
not in nums.
Key Insight: Even though the array is rotated, at least one half is always sorted. We can use this property to eliminate half the search space.
Solution:
1 | class Solution: |
Visualization:
This problem demonstrates one of the most elegant applications of binary search: even when an array isn't fully sorted, we can still use binary search by identifying which half maintains sorted order. The key insight is that in a rotated sorted array, at least one half is always sorted, and we can use this property to eliminate half the search space.
1 | Rotated array: [4, 5, 6, 7, 0, 1, 2] |
Let me provide a clearer step-by-step visualization:
1 | Array: [4, 5, 6, 7, 0, 1, 2] |
This visualization shows how we systematically eliminate half the search space at each step, even though the array is rotated. The critical observation is that by checking which half is sorted and whether the target falls within that sorted half's range, we can always eliminate half the possibilities.
Edge Cases:
- Not rotated:
[1, 2, 3, 4, 5]→ Works normally - Fully rotated:
[5, 1, 2, 3, 4]→ Handled correctly - Single element:
[1]→ Returns correct index - Target not present: Returns
-1
Time Complexity:
LeetCode 162: Find Peak Element
Problem Statement: A peak element is an element that
is strictly greater than its neighbors. Given a 0-indexed integer array
nums, find a peak element, and return its index. If the
array contains multiple peaks, return the index to any of the peaks. You
may imagine that `nums[-1] = nums[n] = -$.
Key Insight: We can use binary search even though
the array isn't sorted! If nums[mid] < nums[mid + 1],
there must be a peak on the right (because we can always go up).
Similarly, if nums[mid] > nums[mid + 1], there's a peak
on the left.
Solution:
1 | class Solution: |
Visualization:
This problem is fascinating because it demonstrates that binary search doesn't always require a fully sorted array. Instead, it relies on a specific property: if we're on an upward slope, there must be a peak to the right; if we're on a downward slope, there must be a peak to the left (or we're already at a peak).
1 | Array: [1, 2, 3, 1] |
Why this works: The key insight is that we can
always make progress toward a peak. If
nums[mid] < nums[mid + 1], we know we're ascending, and
since the boundary is -∞, there must be a peak ahead. If
nums[mid] > nums[mid + 1], we're descending, and the
peak is behind us (possibly at mid itself). This property guarantees
that binary search will converge to a peak.
Why This Works:
- If
nums[mid] < nums[mid + 1], we're on an upward slope. Sincenums[n] = -\infty, there must be a peak to the right. - If
nums[mid] > nums[mid + 1], we're on a downward slope. Sincenums[-1] = -\infty, there must be a peak to the left (possibly at mid).
Time Complexity:
LeetCode 74: Search a 2D Matrix
Problem Statement: Write an efficient algorithm that
searches for a value target in an m x n
integer matrix matrix. This matrix has the following
properties:
- Integers in each row are sorted from left to right
- The first integer of each row is greater than the last integer of the previous row
Approach 1: Treat as 1D Array
1 | class Solution: |
Approach 2: Two Binary Searches
1 | class Solution: |
Example:
1 | Matrix: |
Time Complexity:
Space Complexity:
LeetCode 240: Search a 2D Matrix II
Problem Statement: Write an efficient algorithm that
searches for a value target in an m x n
integer matrix matrix. This matrix has the following
properties:
- Integers in each row are sorted in ascending from left to right
- Integers in each column are sorted in ascending from top to bottom
Key Insight: Unlike Problem 6, we can't treat this as a 1D array because rows don't connect seamlessly. However, we can use a clever approach: start from the top-right corner and eliminate one row or column at a time.
Solution:
1 | class Solution: |
Visualization:
This problem requires a clever insight: we can't use standard binary search because the matrix doesn't have the same properties as Problem 6. However, by starting from the top-right corner, we can eliminate either an entire row or an entire column with each comparison, guaranteeing progress.
The key observation is that from the top-right corner:
- All elements to the left are smaller (because rows are sorted left-to-right)
- All elements below are larger (because columns are sorted top-to-bottom)
- This property allows us to eliminate either a row or column at each step
1 | Matrix: |
This approach is elegant because it guarantees that we eliminate
either a row or column at each step. In the worst case, we eliminate all
rows and columns except one, giving us
Why This Works:
- Starting from top-right, all elements to the left are smaller, all elements below are larger
- If
matrix[row][col] > target, everything in this column below is also larger → eliminate column - If
matrix[row][col] < target, everything in this row to the left is also smaller → eliminate row - Each comparison eliminates either a row or a column, guaranteeing progress
Time Complexity:
Space Complexity:
LeetCode 658: Find K Closest Elements
Problem Statement: Given a sorted integer array
arr, two integers k and x, return
the k closest integers to x in the array. The
result should also be sorted in ascending order. An integer
a is closer to x than an integer
b if |a - x| < |b - x|, or
|a - x| == |b - x| and a < b.
Key Insight: We need to find the left boundary of
the window containing k closest elements. We can use binary
search to find the optimal starting position.
Solution:
1 | class Solution: |
Explanation:
- We're searching for the left boundary of a window of size
k - The search space is
[0, len(arr) - k]because we needkelements - At each step, compare
arr[mid]andarr[mid + k]:- If
x - arr[mid] > arr[mid + k] - x, the right side is closer → move left boundary right - Otherwise, the left side is closer or equal → keep searching left
- If
Example:
This problem requires finding a window of k elements that are closest to x. The key insight is that we can use binary search to find the optimal starting position of this window. We compare the distances from x to the leftmost and rightmost elements of a candidate window to determine which direction to search.
1 | arr = [1, 2, 3, 4, 5], k = 4, x = 3 |
This example demonstrates how binary search can be applied to
optimization problems where we're searching for an optimal position
rather than a specific value. The comparison logic
x - arr[mid] > arr[mid + k] - x elegantly determines
which direction contains the better window.
Time Complexity:
Space Complexity:
Binary Search on Answer
Sometimes, the problem doesn't explicitly ask for binary search, but we can use it to search for the answer in a solution space.
Concept
Instead of searching in an array, we search for the optimal
answer in a range of possible values. This works when: 1. We
can check if a candidate answer is valid 2. The validity function is
monotonic (if answer
LeetCode 875: Koko Eating Bananas
Problem Statement: Koko loves to eat bananas. There
are n piles of bananas, the i-th pile has
piles[i] bananas. The guards have gone and will come back
in h hours. Koko can decide her bananas-per-hour eating
speed of k. Each hour, she chooses some pile of bananas and
eats k bananas from that pile. If the pile has less than
k bananas, she eats all of them instead and will not eat
any more bananas during this hour. Koko wants to finish eating all the
bananas before the guards return. Return the minimum integer
k such that she can eat all the bananas within
h hours.
Solution:
1 | class Solution: |
Key Insight:
- We're not searching in an array, but in the solution
space of possible speeds
[1, max(piles)] - If speed
allows finishing in time, then all speeds also work (monotonic property) - We want the minimum valid speed, so we use the left bound template
Example:
This problem demonstrates binary search on answer space beautifully. We're not searching in an array of speeds, but rather searching for the optimal speed value in a continuous range. Key: recognizing that if a certain speed works, all faster speeds also work (monotonic property), so we can use binary search to find the minimum valid speed.
1 | piles = [3, 6, 7, 11], h = 8 |
This example illustrates the power of binary search on answer space: instead of checking every possible speed from 1 to 11 (which would be 11 checks), binary search finds the answer in only 4 checks, demonstrating logarithmic efficiency even when the answer space isn't explicitly an array.
Time Complexity:
More Binary Search on Answer Problems
- Split Array Largest Sum (LeetCode 410): Binary search on the maximum sum
- Capacity To Ship Packages (LeetCode 1011): Binary search on ship capacity
- Minimize Maximum Distance to Gas Station (LeetCode 774): Binary search on maximum distance
- Kth Smallest Number in Multiplication Table (LeetCode 668): Binary search on the answer value
Common Mistakes and Debugging Tips
Mistake 1: Infinite Loops
Problem: Using left < right with
right = mid - 1
1 | # WRONG |
Fix: Match loop condition with boundary updates:
left <= right→ useright = mid - 1left < right→ useright = mid
Mistake 2: Off-by-One Errors
Problem: Returning wrong index
1 | # WRONG for insertion position |
Fix: Understand what each template returns:
- Left bound template returns insertion position
- Right bound template returns
left - 1for last occurrence
Mistake 3: Integer Overflow
Problem: Using (left + right) // 2
1 | # WRONG (can overflow) |
Mistake 4: Not Handling Empty Arrays
Problem: Accessing nums[0] without
checking
1 | # WRONG |
Debugging Tips
Print mid and boundaries: Add print statements to track search progress
1
2
3
4while left <= right:
mid = left + (right - left) // 2
print(f"left={left}, right={right}, mid={mid}, nums[mid]={nums[mid]}")
# ...Test edge cases:
- Empty array
- Single element
- Two elements
- Target at boundaries
- Target not present
- Duplicate elements (for left/right bound problems)
Verify loop invariants:
- At each iteration, the answer (if exists) is in
[left, right] - The loop terminates (boundaries converge)
- At each iteration, the answer (if exists) is in
Check return value: Make sure you're returning the correct variable (
left,right,mid, orleft - 1)
Complexity Analysis Deep Dive
Why Logarithmic?
Binary search's efficiency comes from the exponential reduction of the search space. prove the time complexity more rigorously.
Recurrence Relation:
Solving the recurrence:
-
Space Complexity
Iterative:
Only uses a constant number of variables:
left,right,midSpace:
Recursive: Each recursive call adds one frame to the stack
Maximum depth:
Space:
Comparison with Other Search Methods
| Method | Time Complexity | Space Complexity | Requirements |
|---|---|---|---|
| Linear Search | None | ||
| Binary Search | Sorted array | ||
| Hash Table | None |
When to use Binary Search:
- Array is sorted (or can be sorted)
- Need to find exact match, range, or insertion position
- Memory is constrained (hash table uses more space)
- Need to solve "binary search on answer" problems
Q&A: Common Questions
Q1: When should I
use left <= right vs left < right?
A: This is one of the most common sources of confusion in binary search. The choice between these two conditions fundamentally changes how the algorithm behaves and what it returns.
Use left <= right when you want to check every
position including when left == right. This is the standard
template for finding an exact match, where you need to verify every
possible position before concluding the target doesn't exist. The loop
continues until the search space is completely exhausted, meaning
left has moved past right.
Use left < right when you're using the left-bound or
right-bound template, where left will converge to the
answer position. In these templates, you're not looking for an exact
match but rather a boundary position. The loop terminates when
left equals right, at which point
left (or left - 1 for right-bound) contains
the answer.
Detailed Example:
Consider searching for target 5 in array
[1, 3, 5, 7, 9]:
With left <= right:
- The loop continues until
left > right - You check position
midwhenleft == right - This ensures you don't miss the target if it's at the boundary
With left < right:
- The loop stops when
left == right - You never check the final position where
left == rightinside the loop - This works for boundary-finding because
leftconverges to the boundary position
When to use each:
- Standard search:
left <= right(check all positions, returnmidor-1) - Insertion position:
left < right(left converges to insertion point) - First occurrence:
left < right(left converges to first occurrence) - Last occurrence:
left < right(left converges to position after last occurrence)
Q2:
Why do we use right = mid instead of
right = mid - 1 in left-bound template?
A: This is a critical distinction that many
programmers struggle with. The reason is that mid itself
might be the answer we're looking for, and we need to keep it in the
search space to ensure we find the leftmost occurrence.
When nums[mid] == target, we've found an occurrence of
the target, but we don't know if it's the leftmost one. There could be
more occurrences to the left. If we set right = mid - 1, we
would exclude mid from consideration, potentially losing
the correct answer. By setting right = mid, we keep
mid in the search space while eliminating everything to its
right.
Detailed walkthrough:
Consider finding the leftmost occurrence of 5 in
[3, 5, 5, 5, 7]:
- Initial:
left=0, right=5 - Iteration 1:
mid=2, nums[2]=5 == 5- If we use
right = mid - 1 = 1: We'd exclude index 2, but index 2 might be the answer (though we know index 1 is actually the leftmost) - If we use
right = mid = 2: We keep index 2 in the search space and continue searching left
- If we use
- Iteration 2:
mid=1, nums[1]=5 == 5- We set
right = mid = 1to continue searching left
- We set
- Iteration 3:
mid=0, nums[0]=3 < 5- We set
left = mid + 1 = 1
- We set
- Now
left=1 == right=1, exit. The answer isleft=1, which is correct.
Key insight: In the left-bound template, we're
searching for the leftmost position where
nums[pos] >= target. The position mid
itself satisfies this condition, so we must keep it in the search space.
Setting right = mid ensures we don't lose valid answers
while still making progress toward the leftmost position.
Q3: How do I know which template to use?
A:
- Standard template: Finding exact match, any occurrence
- Left-bound template: Finding first occurrence, insertion position, minimum valid answer
- Right-bound template: Finding last occurrence, maximum valid answer
Q4: Can binary search work on unsorted arrays?
A: Generally no, but there are exceptions:
- Peak element: Works because of the specific property (at least one half has a peak)
- Rotated sorted array: Works because at least one half is sorted
- Binary search on answer: Works when the validity function is monotonic
Q5: What if the array has duplicates?
A: Standard binary search may return any occurrence.
Use left-bound or right-bound templates to find specific occurrences.
Key: understanding what happens when
nums[mid] == target:
- Left-bound:
right = mid(keep searching left) - Right-bound:
left = mid + 1(keep searching right)
Q6: How do I handle negative numbers or very large numbers?
A: Binary search works the same way. Key: using
left + (right - left) // 2 to avoid overflow. For very
large arrays, ensure your language's integer type can handle the
indices.
Q7: Is binary search always faster than linear search?
A: This is a nuanced question that depends on several factors. While binary search has superior asymptotic complexity, real-world performance involves more than just big-O notation.
For large arrays, binary search is almost always faster. The logarithmic time complexity means that even for arrays with millions of elements, binary search requires only about 20-30 comparisons, compared to potentially millions for linear search.
However, there are important considerations:
Small arrays (
): Linear search might be faster due to overhead. Binary search has more overhead per iteration (calculating mid, multiple comparisons), while linear search is simpler. For very small arrays, the constant factors matter more than the asymptotic complexity. Cache locality: Linear search has better cache performance because it accesses memory sequentially. Modern CPUs are optimized for sequential access patterns, and linear search can benefit from prefetching and cache line utilization. Binary search jumps around in memory, which can cause more cache misses.
Setup cost: Binary search requires a sorted array. If your data isn't already sorted, you need to sort it first, which is
. If you only need to search once, linear search might be faster overall. However, if you need to perform multiple searches, the one-time sorting cost is amortized across all searches. Branch prediction: Modern CPUs use branch prediction to optimize code execution. Linear search has more predictable branching patterns (usually just "continue" until found), while binary search has less predictable branches that can hurt performance on some architectures.
Practical recommendation: Use binary search when:
- The array is already sorted or will be searched multiple times
- The array is reasonably large (
) - You need guaranteed
performance
Use linear search when:
- The array is very small (
) - The array is unsorted and you only need to search once
- Cache performance is critical and the array fits in cache
Q8: How do I modify binary search for descending arrays?
A: Simply reverse the comparison: 1
2
3
4
5
6if nums[mid] == target:
return mid
elif nums[mid] > target: # Reversed!
left = mid + 1
else:
right = mid - 1
Q9:
What's the difference between mid = (left + right) // 2 and
mid = left + (right - left) // 2?
A: Mathematically equivalent, but the second form prevents integer overflow:
- First:
left + rightcan overflow if both are large - Second:
right - leftis safer, then add toleft
Q10: How do I debug a binary search that's not working?
A: 1. Add print statements for
left, right, mid, and
nums[mid] to track the search progress: 1
2
3
4while left <= right:
mid = left + (right - left) // 2
print(f"left={left}, right={right}, mid={mid}, nums[mid]={nums[mid]}")
# ... rest of code
Verify loop condition matches boundary updates:
left <= right→ useright = mid - 1left < right→ useright = mid
Check edge cases systematically:
- Empty array:
[] - Single element:
[1] - Two elements:
[1, 2] - Target at boundaries: first or last element
- Target doesn't exist: smaller than min or larger than max
- Duplicate elements (for left/right bound problems)
- Empty array:
Ensure correct return value:
- Standard search: return
midif found,-1otherwise - Left bound: return
left(but check bounds first) - Right bound: return
left - 1(but check bounds first)
- Standard search: return
Verify array is sorted: Binary search only works on sorted arrays. If your code isn't working, double-check the input.
Trace through examples with duplicates: For left/right bound problems, manually trace through examples like
[1, 2, 2, 2, 3]with target2.Check for infinite loops: If your code hangs, verify that boundaries are actually converging. Add a counter to detect infinite loops:
1
2
3
4iterations = 0
while left < right and iterations < 100:
iterations += 1
# ... rest of code
Q11: How do I handle floating-point binary search?
A: Floating-point binary search is similar but uses a tolerance to determine when to stop:
1 | def binary_search_float(func, target, left, right, tolerance=1e-9): |
Key differences:
- Use
(left + right) / 2.0instead of integer division - Loop condition:
right - left > toleranceinstead ofleft < right - No
+1or-1in updates (floating-point doesn't need it)
Example: Finding square root with precision
1 | def sqrt_binary_search(x, precision=1e-9): |
Q12: Can binary search be used for optimization problems?
A: Yes! Binary search is excellent for optimization problems where: 1. We can check if a solution is feasible 2. The feasibility function is monotonic
Example: Minimize Maximum Distance to Gas Station (LeetCode 774)
Given positions of gas stations and number of new stations to add, minimize the maximum distance between adjacent stations.
1 | def minmaxGasDist(stations, k): |
Q13: How do I modify binary search for descending arrays?
A: Simply reverse the comparison operators:
1 | def binary_search_descending(nums, target): |
Key change: nums[mid] < target
becomes nums[mid] > target because in descending order,
larger values are to the left.
Q14: What's the relationship between binary search and divide-and-conquer?
A: Binary search is a special case of divide-and-conquer where:
- Divide: Split the search space in half by comparing with the middle element
- Conquer: Recursively search in the relevant half
- Combine: Return the result (no combination needed, we just return what we find)
However, binary search is typically implemented iteratively for
better space efficiency (
Recursive version:
1 | def binary_search_recursive(nums, target, left, right): |
Iterative version (preferred):
1 | def binary_search_iterative(nums, target): |
Q15: How do I handle binary search when the array might have duplicates?
A: Use left-bound or right-bound templates depending on what you need:
- Find first occurrence: Use left-bound template
- Find last occurrence: Use right-bound
template
- Find any occurrence: Standard template works, but result is non-deterministic
- Count occurrences: Find both bounds, then
right_bound - left_bound + 1
Example: Count occurrences of target
1 | def count_occurrences(nums, target): |
Advanced Binary Search Patterns
Beyond the standard templates, there are several advanced patterns that appear frequently in competitive programming and technical interviews.
Pattern 1: Binary Search on Answer Space
We've already seen this with "Koko Eating Bananas," but it's worth exploring more deeply. The key insight is that we're not searching in an array, but in a solution space where we can verify if a candidate answer is valid.
When to Use:
- Problem asks for "minimum maximum" or "maximum minimum"
- We can check if a value satisfies the condition
- The validity function is monotonic (if
works, then all work, or vice versa)
Template:
1 | def binary_search_answer(): |
Example: Split Array Largest Sum (LeetCode 410)
Given an array nums and integer m, split
nums into m non-empty subarrays such that the
largest sum among these subarrays is minimized.
1 | class Solution: |
Pattern 2: Binary Search with Custom Comparison
Sometimes, the comparison isn't straightforward. We need to define a custom comparison function.
Example: Search in Rotated Sorted Array with Duplicates (LeetCode 81)
When duplicates exist, nums[left] <= nums[mid]
doesn't guarantee the left half is sorted. We need to handle the case
where nums[left] == nums[mid].
1 | class Solution: |
Pattern 3: Binary Search on Function Values
Instead of searching in an array, we search for a value where a function meets certain criteria.
Example: Sqrt(x) (LeetCode 69)
Find the integer square root of x without using built-in
functions.
1 | class Solution: |
Key Point: Notice
mid = left + (right - left + 1) // 2. This ensures we don't
get stuck when left = mid and
right = left + 1.
Pattern 4: Binary Search with Two Pointers
Combine binary search with two pointers for more complex problems.
Example: 4Sum II (LeetCode 454) - Variant Approach
While this problem has a hash table solution, we can also use binary search by sorting and then using two pointers with binary search for the remaining two numbers.
Pattern 5: Binary Search on Index Range
Sometimes we need to search for an index that satisfies certain properties, not a value.
Example: H-Index II (LeetCode 275)
Given a sorted array of citations, find the h-index using binary search.
1 | class Solution: |
Variations and Extensions
Variation 1: Search in Rotated Arrays
Even though rotated arrays are not fully sorted, at least one half is always sorted, which we can exploit for binary search.
Key Technique: 1. Determine which half is sorted:
nums[left] <= nums[mid] means left half is sorted 2.
Check if target is in the sorted half's range 3. If not in sorted half,
search in the unsorted half
Extended Problems:
- Search in Rotated Sorted Array (no duplicates)
- Search in Rotated Sorted Array II (with duplicates, needs special handling)
- Find Minimum in Rotated Sorted Array
- Find Minimum in Rotated Sorted Array II (with duplicates)
Variation 2: 2D Binary Search
2D matrices can also be searched using binary search by converting 2D indices to 1D indices.
Conversion Formulas:
- 1D index
idx→ 2D coordinates:row = idx // n,col = idx % n - 2D coordinates
(row, col)→ 1D index:idx = row * n + col
Extended Problems:
- Search a 2D Matrix (first element of each row > last element of previous row)
- Search a 2D Matrix II (each row and column sorted, more complex)
Variation 3: Binary Search on Answer
When the answer lies in a range and we can check if a value satisfies the condition, we can binary search in the answer space.
Problem-Solving Steps: 1. Determine the answer range
[left, right] 2. Write a check function
check(mid): determine if mid satisfies the
condition 3. Narrow the search range based on the check result 4. Return
the optimal answer
Classic Problems:
- Koko Eating Bananas
- Split Array Largest Sum
- Capacity To Ship Packages Within D Days
- Minimum Number of Days to Make m Bouquets
Variation 4: Finding Peaks
Even if arrays aren't fully sorted, binary search can work if certain properties are satisfied (e.g., unimodal, bimodal).
Key Insight: Following the upward direction will always lead to a peak.
Extended Problems:
- Find Peak Element
- Peak Index in a Mountain Array
Common Mistakes and Debugging Tips
Mistake 1: Infinite Loops
Cause: Loop condition doesn't match boundary updates.
Wrong Example: 1
2
3
4
5
6
7# WRONG: Using left < right but right = mid - 1
while left < right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1 # Can cause infinite loop!
Fix:
- If using
left <= right, useright = mid - 1 - If using
left < right, useright = mid
Mistake 2: Index Out of Bounds
Cause: Not checking if index is within valid range before returning.
Wrong Example: 1
2
3
4
5def find_left_boundary(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
# ...
return left # WRONG: Didn't check if left is out of bounds
Fix: 1
2
3
4# Check if index is out of bounds
if left >= len(nums) or nums[left] != target:
return -1
return left
Mistake 3: Integer Overflow
Cause: Using (left + right) // 2 to
calculate midpoint.
Fix: Always use
left + (right - left) // 2
Mistake 4: Incorrect Boundary Handling
Common Edge Cases:
- Empty array:
len(nums) == 0 - Single element:
len(nums) == 1 - Target at array boundaries
- Target doesn't exist and is smaller than min / larger than max
- Array has duplicate elements
Debugging Tips:
Print intermediate states:
1
2
3
4while left <= right:
mid = left + (right - left) // 2
print(f"left={left}, right={right}, mid={mid}, nums[mid]={nums[mid]}")
# ...Use assertions:
1
2assert 0 <= left < len(nums), f"left={left} out of range"
assert 0 <= right < len(nums), f"right={right} out of range"Test cases:
[](empty array)[1](single element)[1, 2, 3], target = 1 (at boundary)[1, 2, 3], target = 0 (doesn't exist, smaller than min)[1, 2, 2, 2, 3], target = 2 (with duplicates)
Practical Tips
How to Quickly Identify Binary Search Problems
Consider binary search when you see these characteristics: 1.
Sorted array: Array is already sorted (or can be
sorted) 2. Search target: Need to find a value,
position, or value satisfying a condition 3. Time complexity
requirement: Requires
Decision Tree for Template Selection
1 | What does the problem ask for? |
Problem-Solving Steps
- Determine search space: Searching in array or answer range?
- Choose template: Select appropriate template based on problem requirements
- Determine loop condition:
left <= rightorleft < right? - Write comparison logic: How to update boundaries
based on
nums[mid]andtarget? - Handle edge cases: Empty array, single element, target doesn't exist, etc.
- Verify answer: Check correctness of return value
Performance Optimization Tips
- Early termination: Return immediately if target is found
- Reduce comparisons: Merge similar condition checks
- Space optimization: If only index is needed, don't store full array
Combining with Other Algorithms
- Binary search + sliding window: Use binary search to determine optimal window size when size is uncertain
- Binary search + dynamic programming: Use binary search to optimize DP state transitions when searching is needed
- Binary search + greedy: Use binary search to verify greedy strategy when validation is needed
Real-World Applications of Binary Search
While binary search is fundamental to algorithm interviews, its true power lies in its widespread use across real-world systems. Understanding these applications helps you appreciate why this algorithm is so important and gives you insight into how major systems handle large-scale search operations efficiently.
Database Indexing and Query Optimization
Modern databases rely heavily on binary search for efficient data retrieval. When you create an index on a column in a database like PostgreSQL or MySQL, the database engine typically builds a B-tree or similar data structure that uses binary search principles for lookups.
How it works: When you execute a query like
SELECT * FROM users WHERE id = 12345, the database doesn't
scan every row. Instead, it uses the index structure, which is
essentially a sorted array of key-value pairs. The database performs a
binary search on this index to locate the exact position where
id = 12345 would be, then uses that information to quickly
retrieve the corresponding row from disk.
Performance impact: Without binary search, finding a record in a table with a billion rows would require scanning potentially billions of rows. With binary search on an index, the same operation requires only about 30 comparisons, reducing query time from minutes to milliseconds. This is why database administrators spend significant time designing proper indexes — they're leveraging binary search's logarithmic efficiency.
Example scenario: Consider an e-commerce platform storing millions of product records. When a customer searches for a product by its unique product ID, the database uses binary search on the product ID index to instantly locate the product, rather than scanning through millions of records sequentially.
Version Control Systems: Git Bisect
One of the most elegant applications of binary search is Git's
bisect command, which helps developers find the exact
commit that introduced a bug. This tool demonstrates binary search's
power in problem-solving beyond simple array searching.
How it works: When you discover a bug in your codebase, you know it exists in the current version but didn't exist in some earlier version. Git bisect uses binary search to systematically narrow down which commit introduced the bug. You mark the current commit as "bad" and an earlier known-good commit as "good." Git then checks out the middle commit between these two points, and you test whether the bug exists. Based on your answer, Git eliminates half of the remaining commits and repeats the process.
Visualization: If you have 1000 commits between the
good and bad versions, linear search would require checking up to 1000
commits. Binary search reduces this to at most 10 checks (since
Real-world impact: In large software projects with thousands of commits, manually checking each commit would be impractical. Git bisect makes it feasible to track down bugs introduced weeks or months ago, saving developers countless hours of debugging time.
System Design: Load Balancing and Resource Allocation
Binary search plays a crucial role in distributed systems design, particularly in load balancing and resource allocation scenarios. When systems need to distribute work across multiple servers or allocate resources efficiently, binary search helps find optimal configurations.
Load balancing example: Consider a system that needs to route requests to servers based on their current load. If servers are sorted by their current capacity, binary search can quickly identify which server has the appropriate capacity to handle a new request. This is more efficient than checking every server sequentially, especially in systems with hundreds or thousands of servers.
Resource allocation: In cloud computing platforms, when allocating virtual machines or containers, the system needs to find the smallest available resource that meets the requirements. By maintaining sorted lists of available resources and using binary search, cloud platforms can efficiently match requests to resources, optimizing utilization and reducing allocation time.
Search Engines and Information Retrieval
Search engines use binary search extensively in their indexing and retrieval systems. While the full-text search algorithms are more complex, binary search is fundamental to many underlying operations.
Inverted index lookup: Search engines build inverted indexes that map words to lists of documents containing those words. These lists are typically sorted by document ID or relevance score. When processing a search query, the engine uses binary search to quickly locate specific entries in these sorted lists, enabling fast intersection of multiple word lists to find documents matching complex queries.
Ranking and sorting: When search results need to be sorted by relevance, date, or other criteria, binary search helps maintain sorted order efficiently. This is particularly important when dealing with millions of search results that need to be ranked and presented to users in real-time.
Operating Systems: Memory Management
Operating systems use binary search principles in memory management, particularly in algorithms that manage free memory blocks or page tables.
Buddy system: Some memory allocators use a buddy system where free memory blocks are organized in sorted lists by size. When allocating memory, the system uses binary search to quickly find the smallest block that's large enough for the request, optimizing memory usage.
Page table lookups: In virtual memory systems, page tables need to be searched efficiently. While modern systems use more sophisticated structures like hash tables, binary search principles still apply in various lookup scenarios, especially in systems with limited memory where simpler structures are preferred.
Network Protocols and Routing
Binary search finds applications in network routing and protocol implementations, where efficient lookup of routing tables and protocol handlers is critical for performance.
Routing table lookup: Network routers maintain routing tables that need to be searched quickly to determine where to forward packets. While modern routers use more sophisticated data structures, binary search principles are fundamental to many routing algorithms, especially in software routers and network simulation systems.
Protocol version negotiation: When systems need to negotiate protocol versions or capabilities, they often maintain sorted lists of supported versions. Binary search enables efficient lookup to find the highest compatible version between two systems.
Game Development and Graphics
In game development, binary search is used for various optimization tasks, from collision detection to rendering optimizations.
Spatial partitioning: Game engines often partition space into sorted regions for efficient collision detection. Binary search helps quickly locate which spatial region contains a particular object, enabling efficient collision queries.
Animation and interpolation: When animating between keyframes or interpolating values, binary search can quickly locate the appropriate keyframe range for a given time value, especially when keyframes are stored in sorted arrays.
Financial Systems: Trading and Risk Management
Financial systems use binary search for various operations, from matching orders to calculating risk metrics.
Order book matching: In stock exchanges, buy and sell orders are typically maintained in sorted order books. Binary search enables fast lookup to find matching orders or determine the best available price, which is critical for high-frequency trading where microseconds matter.
Risk calculation: When calculating portfolio risk or performing stress tests, systems often need to search through sorted historical data. Binary search enables efficient lookup of historical prices, volatility measures, and other financial metrics.
Why These Applications Matter
Understanding these real-world applications helps you appreciate binary search beyond interview problems. When you encounter a problem that involves searching through sorted data, maintaining sorted order, or finding optimal values in a range, binary search should be one of the first algorithms you consider. The logarithmic time complexity makes it scalable to massive datasets, which is why it's foundational to so many critical systems.
Moreover, recognizing these patterns helps you identify opportunities to apply binary search in your own projects. Whether you're building a search feature, optimizing database queries, or designing a system that needs efficient lookups, binary search provides a powerful tool for achieving optimal performance.
Summary
Binary search is a powerful algorithm that achieves logarithmic time complexity by eliminating half the search space in each iteration. Mastering it requires:
- Understanding the fundamentals: How elimination works, why it's logarithmic
- Knowing the templates: Standard, left-bound, and right-bound
- Recognizing when to apply: Sorted arrays, rotated arrays, binary search on answer
- Avoiding common mistakes: Infinite loops, off-by-one errors, overflow
- Handling edge cases: Empty arrays, single elements, boundaries, duplicates
Key Takeaways:
- Standard template:
left <= right,right = mid - 1, returnsmidor-1 - Left-bound template:
left < right,right = mid, returnsleft(insertion position) - Right-bound template:
left < right,left = mid + 1, returnsleft - 1(last occurrence) - Always use:
mid = left + (right - left) // 2to prevent overflow - Binary search on answer: Search solution space when validity is monotonic
Practice Problems by Difficulty:
Easy:
- Binary Search (704)
- Search Insert Position (35)
- First Bad Version (278)
Medium:
- Find First and Last Position (34)
- Search in Rotated Sorted Array (33)
- Find Peak Element (162)
- Search a 2D Matrix (74)
Hard:
- Split Array Largest Sum (410)
- Koko Eating Bananas (875)
- Capacity To Ship Packages (1011)
With practice, binary search becomes intuitive, and you'll recognize opportunities to apply it even in problems that don't explicitly mention searching. Key: identifying the monotonic property that allows elimination of half the solution space.
Interview Tips for Binary Search
Binary search is a favorite topic in technical interviews because it tests multiple skills: algorithm knowledge, boundary handling, code quality, and problem-solving approach. Here's how to excel in binary search interview questions.
Before You Start Coding
Clarify the problem: Ask questions to ensure you understand:
- Is the array sorted? In what order (ascending/descending)?
- Are there duplicate elements?
- What should be returned (index, boolean, value, insertion position)?
- What if the target doesn't exist?
- Are there any constraints (array size, value range)?
Discuss your approach: Explain your strategy before coding:
- Which template will you use (standard, left-bound, right-bound)?
- Why this template fits the problem?
- How will you handle edge cases?
Estimate complexity: Mention time and space complexity upfront to show you understand the algorithm's efficiency.
During Coding
Use clear variable names:
left,right,midare standard and clear. Avoid abbreviations.Prevent overflow: Always use
mid = left + (right - left) // 2and mention why:1
2# Good: Mention overflow prevention
mid = left + (right - left) // 2 # Prevents integer overflowComment key decisions: Explain why you chose specific loop conditions or boundary updates:
1
2
3# Using left < right because we want left to converge to insertion position
while left < right:
# ...Handle edge cases explicitly: Don't assume the input is well-formed:
1
2if not nums:
return -1 # Handle empty arrayThink out loud: Explain your thought process as you code. This helps interviewers understand your reasoning and catch mistakes early.
After Coding
Walk through examples: Trace through your code with examples:
- Normal case: target exists
- Edge cases: empty array, single element, target at boundaries
- Special cases: duplicates (for left/right bound problems)
Test your code: Mentally execute your code with test cases:
1
2
3# Example: Search for 5 in [1, 3, 5, 7, 9]
# left=0, right=4
# mid=2, nums[2]=5 == 5 → Found!Discuss optimizations: If time permits, mention potential optimizations:
- Early termination when target is found
- Reducing comparisons by combining conditions
- Space optimizations if applicable
Mention alternatives: Show you know other approaches:
- "We could also use a hash table for O(1) lookup, but that requires O(n) space and the array must be sorted anyway for binary search to work."
Common Interview Scenarios
Scenario 1: "Find the first occurrence of target"
Your response should include:
- "This is a left-bound problem, so I'll use the left-bound template"
- "I'll use left-closed-right-open interval
[left, right)" - "When
nums[mid] == target, I'll setright = midto continue searching left" - "After the loop, I need to check if
leftis valid andnums[left] == target"
Scenario 2: "Search in a rotated sorted array"
Your response should include:
- "Even though the array is rotated, at least one half is always sorted"
- "I'll check which half is sorted by comparing
nums[left]andnums[mid]" - "If target is in the sorted half's range, search there; otherwise search the other half"
- "Handle the edge case where
nums[left] == nums[mid](for duplicates)"
Scenario 3: "Find the minimum value in a rotated sorted array"
Your response should include:
- "This is similar to peak finding - we can use binary search"
- "Compare
nums[mid]withnums[right]to determine which half contains the minimum" - "If
nums[mid] < nums[right], the minimum is in the left half (including mid)" - "Otherwise, the minimum is in the right half"
Red Flags to Avoid
Don't memorize without understanding: Interviewers can tell if you're just reciting code. Understand why each line is there.
Don't skip edge cases: Always mention how you'll handle empty arrays, single elements, boundaries, etc.
Don't ignore integer overflow: Always use the safe midpoint calculation, even in Python where it's less critical.
Don't forget to verify: After coding, verify your solution works for the examples you discussed.
Don't give up on debugging: If your code has a bug, stay calm and debug systematically:
- Add print statements (mentally or on paper)
- Trace through with a small example
- Check your loop condition and boundary updates
Sample Interview Dialogue
Interviewer: "Given a sorted array with duplicates, find the first and last position of target."
You: "I'll use the left-bound and right-bound
templates. Let me clarify: should I return [-1, -1] if
target doesn't exist? [Interviewer confirms] Great. I'll implement two
helper functions: left_bound and right_bound.
The left-bound function uses left < right and
right = mid when nums[mid] >= target. The
right-bound function uses left = mid + 1 when
nums[mid] <= target. After finding both bounds, I'll
check if target exists, and return the range."
Interviewer: "Good approach. Can you code it?"
You: [Code with comments explaining key decisions]
Interviewer: "Walk me through with
nums = [5, 7, 7, 8, 8, 10], target = 8."
You: "For left-bound: Initially
left=0, right=6. mid=3, nums[3]=8 >= 8, so
right=3. mid=1, nums[1]=7 < 8, so
left=2. mid=2, nums[2]=7 < 8, so
left=3. left=3 == right=3, exit. Left bound is
3. For right-bound: [similar walkthrough]. Right bound is 4. So the
answer is [3, 4]."
Interviewer: "What's the time complexity?"
You: "Both binary searches are
This approach demonstrates understanding, clear communication, and thoroughness - exactly what interviewers are looking for.
Additional Interview Dialogue Examples
Scenario 1: Handling Edge Cases
Interviewer: "How would you modify your solution if the array could be empty?"
You: "Good catch! I should add an early return at
the beginning. If len(nums) == 0, I'll immediately return
[-1, -1] since there's nothing to search. This prevents any
index out of bounds errors and handles the edge case explicitly."
Interviewer: "What if the target is smaller than all elements?"
You: "In that case, the left-bound function would
return left=0, but when we check
nums[0] != target, we'd correctly return
[-1, -1]. Similarly, if the target is larger than all
elements, left_bound would return
left=len(nums), and our check
left_idx == len(nums) would catch this and return
[-1, -1]. So the current implementation handles these cases
correctly."
Scenario 2: Optimization Discussion
Interviewer: "Can you optimize this further?"
You: "A few potential optimizations come to mind.
First, if we find the left bound and it's out of bounds or doesn't match
the target, we can return [-1, -1] immediately without
searching for the right bound, since we know the target doesn't exist.
Second, if the array is very large and we're searching for a value that
likely doesn't exist, we could first do a quick standard binary search
to check existence before finding bounds. However, for most cases, the
current
Interviewer: "What if we needed to find the count of occurrences?"
You: "That's straightforward! Once we have both
bounds, if the target exists, the count is simply
right_idx - left_idx + 1. If the target doesn't exist (we
return [-1, -1]), the count would be 0. This is actually
more efficient than scanning the entire array, which would be
Scenario 3: Alternative Approaches
Interviewer: "Could you solve this with a single binary search?"
You: "Interesting question! While it's theoretically
possible to find both bounds in a single pass by tracking additional
state, it would be more complex and wouldn't improve the time complexity
— we'd still need
Interviewer: "What if the array had millions of elements and we needed to do this search many times?"
You: "In that case, we might consider preprocessing.
If we're searching for the same target multiple times, we could cache
the results. If we're searching for different targets but the array
doesn't change, we could build additional data structures like a hash
map of value-to-range mappings, but that would require
- Post title:LeetCode (5): Binary Search
- Post author:Chen Kai
- Create time:2023-06-15 00:00:00
- Post link:https://www.chenk.top/en/leetcode-binary-search/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.