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, then return its index. Otherwise, return -1
.
You must write an algorithm with O(log n)
runtime complexity.
Example 1:
Input: nums = [-1,0,3,5,9,12], target = 9 Output: 4 Explanation: 9 exists in nums and its index is 4
Example 2:
Input: nums = [-1,0,3,5,9,12], target = 2 Output: -1 Explanation: 2 does not exist in nums so return -1
Constraints:
1 <= nums.length <= 104
-104 < nums[i], target < 104
nums
are unique.nums
is sorted in ascending order.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force approach to searching a sorted list is like manually checking every item until you find the one you're looking for. It's straightforward: you simply go through each item in order, one by one, until you locate the target value.
Here's how the algorithm would work step-by-step:
def linear_search(sorted_list, target_value):
list_length = len(sorted_list)
# Iterate through each element in the sorted list.
for current_index in range(list_length):
current_element = sorted_list[current_index]
# Check if the current element matches the target.
if current_element == target_value:
return current_index
# Exit early if we surpass the target, due to list being sorted
if current_element > target_value:
return -1
# Return -1 if target isn't found after checking all elements.
return -1
The most efficient way to find a specific value in a sorted list is to repeatedly cut the list in half. We eliminate half of the remaining possibilities with each step, quickly narrowing down our search.
Here's how the algorithm would work step-by-step:
def binary_search(sorted_list, target_value):
left_index = 0
right_index = len(sorted_list) - 1
while left_index <= right_index:
middle_index = (left_index + right_index) // 2
middle_value = sorted_list[middle_index]
# Found the target, so return the index.
if middle_value == target_value:
return middle_index
# Target is in the left half.
if target_value < middle_value:
right_index = middle_index - 1
# Target is in the right half.
else:
left_index = middle_index + 1
# Target not found in the list.
return -1
Case | How to Handle |
---|---|
Null or empty input array | Return -1 immediately as binary search cannot operate on an empty or null array. |
Array with one element | Return -1 as the element either matches or doesn't match the target. |
Target value less than the smallest element in the sorted array | Binary search will converge to the first element, mid < target always, and return -1. |
Target value greater than the largest element in the sorted array | Binary search will converge to the last element, mid > target always, and return -1. |
Target value equals the first element of the array | The algorithm should correctly find the target at index 0. |
Target value equals the last element of the array | The algorithm should correctly find the target at index array.length -1. |
Array contains duplicate target values | Binary search may return any one of the indices where the target is found, but the question probably expects just ANY match. |
Integer overflow when calculating mid = (low + high) / 2 | Use mid = low + (high - low) / 2 to prevent potential integer overflow in languages like Java or C++. |