17. Binary Search

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, return its index. Otherwise, return -1. You must write an algorithm with O(log n) runtime complexity.

Examples:

Input: nums = [-1,0,3,5,9,12], target = 9
Output: 4
Explanation: 9 exists in nums and its index is 4.

Input: nums = [-1,0,3,5,9,12], target = 2
Output: -1
Explanation: 2 does not exist in nums so return -1.

Problem Breakdown:

  1. Set up two pointers for the search boundaries: left at index 0 and right at the last index.
    • left = 0
      right = len(nums) - 1
  2. Loop while left <= right. Calculate the middle index to avoid overflow using left + (right - left) // 2.
    • while left <= right:
          mid = left + (right - left) // 2
  3. If the middle element equals the target, return mid. If it is less than target, search the right half by setting left = mid + 1.
    • if nums[mid] == target:
          return mid
      elif nums[mid] < target:
          left = mid + 1
  4. If the middle element is greater than target, search the left half by setting right = mid - 1. If the loop ends, return -1.
    • else:
          right = mid - 1
      return -1

Summary:

Binary search repeatedly halves the search space. Compare the target with the middle element: if equal, return the index; if larger, search right; if smaller, search left. This halving gives O(log n) time.

Time and Space Complexity:

Time Complexity: O(log n) - we halve the search space each iteration.

Space Complexity: O(1) - only constant extra space used.

Python Solution:

def search(nums, target):
    left, right = 0, len(nums) - 1
    while left <= right:
        mid = left + (right - left) // 2
        if nums[mid] == target:
            return mid
        elif nums[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

JavaScript Solution:

var search = function(nums, target) {
    let left = 0, right = nums.length - 1;
    while (left <= right) {
        const mid = Math.floor((left + right) / 2);
        if (nums[mid] === target) return mid;
        else if (nums[mid] < target) left = mid + 1;
        else right = mid - 1;
    }
    return -1;
};

Java Solution:

class Solution {
    public int search(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) return mid;
            else if (nums[mid] < target) left = mid + 1;
            else right = mid - 1;
        }
        return -1;
    }
}