Binary Search Fundamentals
Binary search is a divide-and-conquer algorithm that finds an element in a sorted array by repeatedly halving the search space.
How It Works
- Compare target with middle element
- If target equals middle → found
- If target < middle → search left half
- If target > middle → search right half
- Repeat until found or search space is empty
Visual Example
Sorted Array: [2, 5, 8, 12, 16, 23, 38, 56, 72, 91]
Target: 23
Step 1: low=0, high=9, mid=4 → arr[4]=16 < 23 → search right
Step 2: low=5, high=9, mid=7 → arr[7]=56 > 23 → search left
Step 3: low=5, high=6, mid=5 → arr[5]=23 = 23 → FOUND!
Iterative Implementation (Preferred)
public int binarySearch(int[] arr, int target) {
int low = 0;
int high = arr.length - 1;
while (low <= high) {
int mid = low + (high - low) / 2; // Prevents overflow
if (arr[mid] == target) {
return mid; // Found
} else if (arr[mid] < target) {
low = mid + 1; // Search right half
} else {
high = mid - 1; // Search left half
}
}
return -1; // Not found
}
Recursive Implementation
public int binarySearchRecursive(int[] arr, int target, int low, int high) {
if (low > high) {
return -1; // Base case: not found
}
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
return mid;
} else if (arr[mid] < target) {
return binarySearchRecursive(arr, target, mid + 1, high);
} else {
return binarySearchRecursive(arr, target, low, mid - 1);
}
}
Why low + (high - low) / 2?
// WRONG: Can cause integer overflow
int mid = (low + high) / 2;
// If low = 1,000,000,000 and high = 2,000,000,000
// low + high = 3,000,000,000 > Integer.MAX_VALUE
// CORRECT: Prevents overflow
int mid = low + (high - low) / 2;
// Equivalent to low + (high - low) / 2
// Both expressions give same result, but second is safe
Complexity Analysis
| Aspect | Complexity |
|---|---|
| Time (best) | O(1) - found at middle |
| Time (worst) | O(log n) - search space halved each step |
| Time (average) | O(log n) |
| Space (iterative) | O(1) |
| Space (recursive) | O(log n) - call stack |
Binary Search Variations
Variation 1: Finding First Occurrence
Useful when array has duplicates.
public int findFirst(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid; // Record position
high = mid - 1; // Continue searching left
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
Variation 2: Finding Last Occurrence
public int findLast(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) {
result = mid; // Record position
low = mid + 1; // Continue searching right
} else if (arr[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
Variation 3: Finding Floor and Ceil
Floor: Largest element ≤ target
Ceil: Smallest element ≥ target
// Floor - largest element <= target
public int findFloor(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] <= target) {
result = arr[mid];
low = mid + 1;
} else {
high = mid - 1;
}
}
return result;
}
// Ceil - smallest element >= target
public int findCeil(int[] arr, int target) {
int low = 0, high = arr.length - 1;
int result = -1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] >= target) {
result = arr[mid];
high = mid - 1;
} else {
low = mid + 1;
}
}
return result;
}
When to Use Binary Search
- Sorted array - classic binary search
- Monotonic function - function that only increases or decreases
- Search space is ordered - can eliminate half each step
- Finding minimum/maximum with constraint - binary search on answer
Common Mistakes
- Off-by-one errors -
low <= highvslow < high - Integer overflow - use
low + (high - low) / 2 - Infinite loops - ensure
lowandhighalways change - Wrong midpoint calculation - always use safe formula
Interactive Visualization
Binary Search Visualization
Practice Problems
Given a rotated sorted array and a target value, return its index.
Example:
Input: nums = [4,5,6,7,0,1,2], target = 0
Output: 4
Array rotated at index 3. Target 0 at index 4.
Edge Cases:
- Single element — match or return -1
- Target not in array
- Array not rotated (same as sorted)
- Rotation at boundary — last element is minimum
- Target is the pivot element
Given a rotated sorted array, find the minimum element.
Example:
Input: nums = [3,4,5,1,2]
Output: 1
Minimum is 1 at index 3.
Edge Cases:
- Not rotated (already sorted): first element is minimum
- Single element: return that element
- Two elements: return min of both
Write an efficient algorithm that searches for a value in an m x n matrix. Each row is sorted and the first integer of each row is greater than the last integer of the previous row.
Example:
Input: matrix = [[1,3,5,7],[10,11,16,20],[23,30,34,60]], target = 3
Output: true
3 is found in the matrix.
Optimal Solution — O(log(m*n)) time, O(1) space
Binary search treating matrix as 1D array
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int low = 0, high = m * n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
int val = matrix[mid / n][mid % n];
if (val == target) return true;
else if (val < target) low = mid + 1;
else high = mid - 1;
}
return false;
}
} Edge Cases:
- Single element matrix
- Target at corners
- Target not found
Quiz
1. What is the time complexity of binary search?
2. Why should you use `low + (high - low) / 2` instead of `(low + high) / 2`?
3. What is a common mistake when implementing Binary Search?
Flashcards
Question
What is the time complexity of binary search?
Click to reveal answer
Answer
O(log n) - the search space is halved with each comparison.
Question
When can you apply binary search?
Click to reveal answer
Answer
When the search space is ordered or you have a monotonic function that divides the space into valid/invalid regions.
Question
Binary Search best practices
Click to reveal answer
Answer
Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.
Revision Notes
Key Takeaways
- 1. Binary search requires sorted data or monotonic function
- 2. Use safe midpoint formula to prevent integer overflow
- 3. Iterative approach is preferred (O(1) space)
- 4. Apply to rotated arrays by determining which half is sorted
Interview Tips
- • Clarify if array is sorted before applying binary search
- • Ask about duplicates - affects first/last occurrence approach
- • Discuss edge cases: empty array, single element, target not found
- • Mention time complexity advantage over linear search
Cheat Sheet
Binary Search Cheat Sheet
Template:
int low = 0, high = n - 1;
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == target) return mid;
else if (arr[mid] < target) low = mid + 1;
else high = mid - 1;
}
Variations:
- First occurrence: move
high = mid - 1when found - Last occurrence: move
low = mid + 1when found - Floor/Ceil: track result before narrowing
Key Points:
- Always use
low + (high - low) / 2for overflow safety - Array must be sorted (or function must be monotonic)
- O(log n) time, O(1) space (iterative)