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
The problem asks to find the index where a target
value should be inserted into a sorted array nums
to maintain its sorted order. If the target
already exists, return its index.
Two main approaches are presented:
Approach 1: Iterative Binary Search
This approach leverages the efficiency of binary search because the input array is sorted. The core idea is to repeatedly halve the search space until the target is found or the search space is exhausted.
Algorithm:
l
(left) and r
(right), to the start and end of the array (inclusive and exclusive, respectively).l < r
:
mid = (l + r) // 2
(integer division).nums[mid] >= target
, the target (if present) is in the left half, so update r = mid
.l = mid + 1
.l
. This is because after the loop finishes, l
points to the index where the target
should be inserted. If target
was found, l
will be its index.Time Complexity: O(log n), where n is the length of the array. This is the characteristic time complexity of binary search.
Space Complexity: O(1), as we use only a constant amount of extra space.
Approach 2: Using Built-in Binary Search Functions
Many programming languages provide built-in functions for binary search. These functions often return either the index of the found element or a negative value indicating the insertion point.
Algorithm:
bisect_left(nums, target)
from the bisect
module. This function returns the index where target
should be inserted to maintain order.Arrays.binarySearch(nums, target)
. This function returns the index if target
is found; otherwise, it returns -insertion_point - 1
.lower_bound(nums.begin(), nums.end(), target) - nums.begin()
. This finds the iterator to the first element not less than target
, and subtracts the beginning iterator to get the index.sort.SearchInts(nums, target)
. This function returns the index where the target should be inserted.Time Complexity: O(log n), as it is based on the underlying binary search algorithm of the built-in function.
Space Complexity: O(1), as it usually uses a constant amount of extra space.
Code Examples (Approach 1 - Iterative Binary Search):
The code examples below demonstrate the iterative binary search approach in multiple languages. The core logic remains the same, differing only in syntax and function names.
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
l, r = 0, len(nums)
while l < r:
mid = (l + r) // 2
if nums[mid] >= target:
r = mid
else:
l = mid + 1
return l
class Solution {
public int searchInsert(int[] nums, int target) {
int l = 0, r = nums.length;
while (l < r) {
int mid = (l + r) >>> 1; // Use >>> for unsigned right shift
if (nums[mid] >= target) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
}
class Solution {
public:
int searchInsert(vector<int>& nums, int target) {
int l = 0, r = nums.size();
while (l < r) {
int mid = (l + r) >> 1;
if (nums[mid] >= target) {
r = mid;
} else {
l = mid + 1;
}
}
return l;
}
};
(Other languages like Go, JavaScript, TypeScript, Rust, and PHP would have similar implementations with minor syntactic variations.)
Code Examples (Approach 2 - Built-in Functions):
This approach is even more concise, leveraging the language's built-in binary search capabilities.
import bisect
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
return bisect.bisect_left(nums, target)
import java.util.Arrays;
class Solution {
public int searchInsert(int[] nums, int target) {
int i = Arrays.binarySearch(nums, target);
return i < 0 ? -i - 1 : i;
}
}
(Similar concise solutions exist for C++, Go, and other languages with built-in binary search functions.)
Both approaches offer optimal O(log n) time complexity, making them efficient for large input arrays. The choice between them depends on preference and whether you want to utilize built-in functions for brevity.