Description
Given an array of integers nums
sorted in non-decreasing order, find the starting and ending position of a given target
value.
If target
is not found in the array, return [-1, -1]
.
You must write an algorithm with O(log n)
runtime complexity.
Example 1:
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]
Example 2:
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
Example 3:
Input: nums = [], target = 0
Output: [-1,-1]
Constraints:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
is a non-decreasing array.
-109 <= target <= 109
Solutions
Solution 1: Binary Search
We can perform two binary searches to find the left boundary and the right boundary.
The time complexity is $O(\log n)$, where $n$ is the length of the array $\textit{nums}$. The space complexity is $O(1)$.
| class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
l = bisect_left(nums, target)
r = bisect_left(nums, target + 1)
return [-1, -1] if l == r else [l, r - 1]
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 | class Solution {
public int[] searchRange(int[] nums, int target) {
int l = search(nums, target);
int r = search(nums, target + 1);
return l == r ? new int[] {-1, -1} : new int[] {l, r - 1};
}
private int search(int[] nums, int x) {
int left = 0, right = nums.length;
while (left < right) {
int mid = (left + right) >>> 1;
if (nums[mid] >= x) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}
|
| class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int l = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
int r = lower_bound(nums.begin(), nums.end(), target + 1) - nums.begin();
if (l == r) {
return {-1, -1};
}
return {l, r - 1};
}
};
|
| func searchRange(nums []int, target int) []int {
l := sort.SearchInts(nums, target)
r := sort.SearchInts(nums, target+1)
if l == r {
return []int{-1, -1}
}
return []int{l, r - 1}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 | function searchRange(nums: number[], target: number): number[] {
const search = (x: number): number => {
let [left, right] = [0, nums.length];
while (left < right) {
const mid = (left + right) >> 1;
if (nums[mid] >= x) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
};
const l = search(target);
const r = search(target + 1);
return l === r ? [-1, -1] : [l, r - 1];
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 | impl Solution {
pub fn search_range(nums: Vec<i32>, target: i32) -> Vec<i32> {
let n = nums.len();
let search = |x| {
|