
Binary Search is one of the most fundamental algorithms in computer science, widely used for efficiently searching in sorted structures. Its core idea is simple yet powerful: instead of scanning every element linearly, it repeatedly divides the search space in half, reducing the problem size exponentially at each step. This leads to a time complexity of , which is significantly faster than a linear scan for large datasets.
The algorithm works on the principle of divide and conquer. Given a sorted array, we compare the target element with the middle element. If the target equals the middle element, the search terminates successfully. If the target is smaller, the search continues in the left half; if larger, in the right half. This halving continues until the search space becomes empty or the element is found.
Here is a canonical TypeScript implementation:
function binarySearch(arr: number[], target: number): number {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor(left + (right - left) / 2);
if (arr[mid] === target) {
return mid;
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
Several subtle but important details are worth noting:
mid as left + (right - left) / 2 prevents integer overflow, which can occur if left + right exceeds the maximum integer value.
While JavaScript/TypeScript numbers are safe, this is critical in languages like Java or C++.Binary Search is more than just a search algorithm. It forms the foundation for numerous patterns and problem-solving techniques, including:
All these variations can be tackled with a few core adaptations of the basic Binary Search. For example, to search on rotated sorted arrays, we can modify the comparison logic to determine which half is properly sorted and adjust our search accordingly.
function search(nums: number[], target: number): number {
let left = 0
let right = nums.length - 1
while (left <= right) {
let mid = left + Math.floor((right - left) / 2)
if (nums[mid] === target) {
return mid
}
if (nums[left] <= nums[mid]) {
if (nums[left] <= target && target < nums[mid]) {
right = mid - 1
} else {
left = mid + 1
}
} else {
if (nums[mid] < target && target <= nums[right]) {
left = mid + 1
} else {
right = mid - 1
}
}
}
return -1
};
Binary Search works by repeatedly halving the search space until the target element is found or the space becomes empty. At each step, only a single comparison is performed, resulting in very efficient logarithmic behavior.
The number of iterations depends on the size of the input array:
For this reason:
For what concerns space complexity, Binary Search can be implemented iteratively with no extra memory allocation:
As a result:
| Problem | Technique | Solution |
|---|---|---|
| Search Insert Position | Binary Search | Solution |
| Find First and Last Position of Element in Sorted Array | Binary Search | Solution |
| Search in Rotated Sorted Array | Binary Search | Solution |
| Find Peak Element | Binary Search | Solution |
| Random Pick with Weight | Binary Search | Solution |
| Koko Eating Bananas | Binary Search on Answer | Solution |
| Find Minimum in Rotated Sorted Array | Binary Search | Solution |
| Search a 2D Matrix | Binary Search | Solution |
| Find in Mountain Array | Binary Search | Solution |
| Median of Two Sorted Arrays | Binary Search | Solution |