AlgorithmsBinary Search

Binary Search

Divide and conquer approach to search sorted data, significantly reducing search time.

Definition

Binary Search is a searching algorithm that finds a target value in a sorted array or a range of numbers by repeatedly dividing the search space in half. Imagine you’re looking for a specific page in a phone book: instead of scanning every page, you flip to the middle, quickly decide if the target is in the first or second half, and eliminate half of the possibilities with each step. With every comparison, it “zooms” in on the target, achieving impressive efficiency with a time complexity of O(log n).

Binary Search in Sorted Array

Picture yourself trying to find something in an encyclopedia that’s sorted in alphabetical order. Instead of reading every page, you open the encyclopedia to its center, compare the name you see with the one you’re searching for, and then decide which half of the encyclopedia holds your answer. In a similar way, binary search in an array uses two pointers: left at the very beginning and right at the end. Each iteration calculates the middle index, where the element is compared with the target.

def binary_search(nums: list[int], target: int) -> int:
    # Start left and right at both ends of the array
    left, right = 0, len(nums) - 1
    
    while left <= right:
        # Calculate the mid point
        mid = (left + right) // 2
        
        # Move left to search higher values
        if nums[mid] < target:
            left = mid + 1
        # Move right to search lower values
        elif nums[mid] > target:
            right = mid - 1
        # Found target at mid
        else:
            return mid
    
    # Target not found
    return -1

If the middle element is less than the target, you move the left pointer to middle + 1, effectively ignoring the left portion. On the other hand, if it’s greater, you adjust the right pointer to middle - 1. This narrowing-down process is what makes binary search so efficient — each step significantly reduces the number of candidates, ensuring that even massive arrays can be searched quickly.

Binary Search in Range

Binary Search isn’t just for arrays - you can use it to find answers within any range of numbers or answer space. For example, you might want to find the smallest container size that fits all your items, or the fastest speed your system can run without overheating. In these cases, instead of searching through an array, you’re searching through a range of possible answers. The key is that the answer must be one-directional.

def binary_search_range(low: int, high: int, condition) -> int:
    # Start left and right at the range boundaries
    left, right = low, high
    
    while left <= right:
        # Calculate the mid point
        mid = (left + right) // 2
        
        # Check if mid satisfies our condition
        if condition(mid):
            # Move right to find smallest valid value
            right = mid - 1
        else:
            # Move left to find a valid value
            left = mid + 1
    
    # Return the smallest valid value (depends on problem)
    return left

In these cases, you select a candidate value from the answer space and test it. Based on whether it satisfies your condition, you adjust the search boundaries. With each iteration, half of the possible answers are eliminated, steering you rapidly toward the optimal solution. This approach is especially useful when a direct formula isn’t available, and trial-and-error must be guided by the structure of the problem.

How it Works

Binary Search is an efficient algorithm that quickly narrows down the search space to locate a target value. When working with a sorted array, we start by setting the left pointer at index 0 and the right pointer at index length - 1. For a range of numbers, the pointers are placed at the lower and upper bounds, such as 1 and the maximum value. The algorithm’s core is a while loop with the condition left <= right, which ensures that even when both pointers meet, that final candidate is still checked.


Each step starts by finding the middle position using division. We then check if the middle element is our target value. If it matches, we‘ve found what we‘re looking for. If the middle is too small, we move left to middle + 1 to search higher values. If it‘s too large, we move right to middle - 1 to search lower values. With each step, we eliminate half of our search area, making the process very efficient.


This method guarantees that no possible candidate is overlooked, even when only one element is left to be checked. The while (left <= right) condition is key for handling edge cases, making sure that the algorithm checks every candidate until the pointers cross. By reducing the search space, the algorithm achieves a time complexity of O(log n) and maintains a constant space complexity of O(1).

Binary Search: Step-by-Step

1. Initialize Boundaries

Begin by setting the left pointer to 0 and the right pointer to n - 1, where n is the length of your sorted array or the size of your numeric range.

2. Calculate Middle Index

Compute the middle index using the formula middle = left + Math.floor((right - left) / 2). This calculation prevents potential overflow and accurately pinpoints the midpoint of the current search space.

3. Compare with Target

Compare the element at the middle index with your target value. If they match, you‘ve found your result. Otherwise, determine whether to search in the left or right half of the array.

4. Update Boundaries

If the middle element is less than the target, move the left pointer to middle + 1. Conversely, if it’s greater, shift the right pointer to middle - 1. This step effectively eliminates half of the remaining elements from consideration.

5. Process Result

Repeat the above steps until the left pointer exceeds the right pointer, which indicates that the target is not present. If the target is found, return its index; otherwise, return an appropriate value (such as -1) to signal absence.
Common Patterns

Binary Search problems follow a consistent pattern using a while loop where left <= right. Each step calculates the middle point and makes a decision that eliminates half of the remaining possibilities. Look for problems that mention “sorted arrays“, “finding a specific value“, or anything requiring you to minimize or maximize a value within a range. The key is recognizing when your problem has a clear way to eliminate half the possibilities with each step.


You can also use Binary Search when searching through a range of possible answers instead of an array. These problems often ask you to find the “minimum value that satisfies“ or “maximum value that works“. The crucial requirement is that the answer space must be monotonic once a value satisfies your condition, all values after it must also satisfy it. For example, if a certain speed is too slow, all slower speeds will also be too slow.

Best Practices

Mastering Binary Search is key to solving many algorithmic problems efficiently. Here are some best practices to help you implement Binary Search effectively and avoid common pitfalls:


Binary Search is ideal for problems involving sorted arrays or ordered data. It is also very effective in scenarios where you work with a monotonic function, such as searching for the optimal value in an answer space.

Practice Problems
Binary Search
Completed
Title
Notes
Solution
Medium
Medium
Medium
Medium
Medium
Hard

Copyright © StudyDSA. All rights reserved.