问题背景
给你一个按照非递减顺序排列的整数数组
n
u
m
s
nums
nums,和一个目标值
t
a
r
g
e
t
target
target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值
t
a
r
g
e
t
target
target,返回
[
−
1
,
−
1
]
[-1, -1]
[−1,−1]。
你必须设计并实现时间复杂度为
O
(
l
o
g
n
)
O(log n)
O(logn) 的算法解决此问题。
数据约束
- 0 ≤ n u m s . l e n g t h ≤ 1 0 5 0 \le nums.length \le 10 ^ 5 0≤nums.length≤105
- − 1 0 9 ≤ n u m s [ i ] ≤ 1 0 9 -10 ^ 9 \le nums[i] \le 10 ^ 9 −109≤nums[i]≤109
- n u m s nums nums 是一个非递减数组
- − 1 0 9 ≤ t a r g e t ≤ 1 0 9 -10 ^ 9 \le target \le 10 ^ 9 −109≤target≤109
解题过程
二分查找模板题,第一个位置完全符合二分方法的含义,直接调用计算即可;最后一个位置,可以转化为第一个大于目标元素的位置的前一个位置。
如果第一个符合条件的位置就没找到,那么最后一个当然也是无稽之谈。所以可以在判断到出现这种情况时,及时返回没找到的结果。
具体实现
class Solution {
public int[] searchRange(int[] nums, int target) {
int first = binarySearch(nums, target);
if(first == nums.length || nums[first] != target) {
return new int[]{-1, -1};
}
int last = binarySearch(nums, target + 1) - 1;
return new int[]{first, last};
}
private int binarySearch(int[] nums, int target) {
int left = 0, right = nums.length;
while(left < right) {
int mid = left + ((right - left) >>> 1);
if(nums[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}