Given a sorted array of distinct integers and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
You must write an algorithm with O(log n)
runtime complexity.
Example 1:
Input: nums = [1,3,5,6], target = 5 Output: 2
Example 2:
Input: nums = [1,3,5,6], target = 2 Output: 1
Example 3:
Input: nums = [1,3,5,6], target = 7 Output: 4
Constraints:
1 <= nums.length <= 104
-104 <= nums[i] <= 104
nums
contains distinct values sorted in ascending order.-104 <= target <= 104
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:
Imagine you are looking for a specific page in a book where the pages are already sorted in ascending order. The brute force approach would mean going through each page, one by one, until you either find the exact page or find where it should be if it were present.
Here's how the algorithm would work step-by-step:
def search_insert_position_brute_force(sorted_numbers, target_number):
for index in range(len(sorted_numbers)):
# Check if the current number is equal to the target.
if sorted_numbers[index] == target_number:
return index
# Check if the target should be inserted before the current number
if sorted_numbers[index] > target_number:
return index
# If target is greater than all numbers, insert at the end
return len(sorted_numbers)
The efficient way to solve this is to repeatedly cut the search area in half. We use the sorted nature of the input to quickly eliminate large sections, getting us to the right spot faster than checking each place individually.
Here's how the algorithm would work step-by-step:
def search_insert_position(number_array, target_value):
left_index = 0
right_index = len(number_array) - 1
while left_index <= right_index:
middle_index = (left_index + right_index) // 2
middle_value = number_array[middle_index]
# If the target is found, return the index.
if middle_value == target_value:
return middle_index
# Adjust search range if target is smaller.
if middle_value > target_value:
right_index = middle_index - 1
# Adjust search range if target is larger.
else:
left_index = middle_index + 1
# If target is not found, return insertion index.
# Left index is where the element should be inserted.
return left_index
Case | How to Handle |
---|---|
Empty input array (nums is null or has length 0) | Return 0 since the target would be inserted at the beginning. |
Target is smaller than the first element in nums | Return 0 as the target belongs at the beginning of the array. |
Target is larger than the last element in nums | Return nums.length as the target belongs at the end of the array. |
nums contains a single element and target is equal to it | Return 0, the index of the single element. |
Large input array to ensure binary search scales efficiently | Use binary search algorithm for logarithmic time complexity O(log n). |
Integer overflow when calculating mid in binary search (especially in languages like Java/C++) | Use mid = low + (high - low) / 2 to prevent overflow instead of mid = (low + high) / 2. |
Array contains very large numbers that could cause overflow when target is added to an element | The comparison-based approach of binary search avoids summing array elements with the target so no overflow happens. |
Target is present in the array. | The binary search should return the index of the existing element. |