Back to Home
Binary Search
Binary Search efficiently finds a target value in a sorted array by repeatedly dividing the search space in half. It can also be used to find optimal values in monotonic search spaces.
When to Use
- Array is sorted (or can be sorted)
- Problem asks to find a target or boundary
- Search space is monotonic
- Problems asking for 'minimum/maximum value that satisfies condition'
Common Patterns
Standard Binary Search
Find exact target in sorted array
Example: Search in rotated sorted array
Binary Search on Answer
Find optimal value in monotonic search space
Example: Koko eating bananas, capacity to ship packages
Finding Boundaries
Find first/last occurrence or insertion position
Example: First bad version, search insert position
Code Templates
Python
# Standard binary search
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
# Binary search on answer template
def binary_search_answer(arr):
def feasible(value):
# Check if value satisfies the condition
pass
left, right = min_possible, max_possible
result = -1
while left <= right:
mid = left + (right - left) // 2
if feasible(mid):
result = mid
# Search for better answer
right = mid - 1 # or left = mid + 1
else:
left = mid + 1 # or right = mid - 1
return result
# Find leftmost/rightmost boundary
def find_boundary(arr, target):
left, right = 0, len(arr) - 1
result = -1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
result = mid
right = mid - 1 # Continue searching left
# Use left = mid + 1 for rightmost
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return resultC++
// Standard binary search
int binarySearch(vector<int>& arr, int target) {
int left = 0, right = arr.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
// Binary search on answer template
int binarySearchAnswer(vector<int>& arr) {
auto feasible = [&](int value) -> bool {
// Check if value satisfies the condition
return true;
};
int left = minPossible, right = maxPossible;
int result = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (feasible(mid)) {
result = mid;
// Search for better answer
right = mid - 1; // or left = mid + 1
} else {
left = mid + 1; // or right = mid - 1
}
}
return result;
}
// Find leftmost/rightmost boundary
int findBoundary(vector<int>& arr, int target) {
int left = 0, right = arr.size() - 1;
int result = -1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) {
result = mid;
right = mid - 1; // Continue searching left
// Use left = mid + 1 for rightmost
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return result;
}Practice Problems
Common Pitfalls
- ⚠️Integer overflow when calculating mid (use left + (right - left) / 2)
- ⚠️Infinite loops due to incorrect pointer updates
- ⚠️Off-by-one errors in boundary conditions
- ⚠️Wrong loop condition (left < right vs left <= right)
Complexity
Time
O(log n)
Space
O(1) iterative, O(log n) recursive
Logarithmic time is very efficient for large datasets