题意:
给你一个可能有重复元素的上升序列,让你找出目标值所在的下标范围,如果不存在则返回【-1,-1】;
思路:
先来一个二分查找,看能不能找到目标值,如果找不到则不存在,如果找到了,记录下标为pos;
然后在区间【0,pos】二分找左边界,在区间【pos,nums.length-1】二分找右边界;
但是这两个二分的写法稍有不同。
对于找左边界:
所找目标值要尽量往左,因为mid的求法是往右取整的,mid值大于等于目标值时,修改r = mid,否则修改l = mid+1。
对于找右边界:
所找目标值要尽量往右,因为mid的求法是往右取整的,mid值小于等于目标值时记录l = mid+1(为了靠右,如果相等,记录mid的下标//res = mid),否则r = mid-1;
循环条件要改为l<=r,循环结束后,右边界等于res;
java代码:
class Solution {
public int[] searchRange(int[] nums, int target) {
int l = 0;
int r = nums.length;
int[] ans = new int[2];
ans[0] = ans[1] = -1;
if(r==0){
return ans;
}
r-=1;
int pos = -1;
while(l<=r){
int mid = (l+r)>>1;
pos = mid;
if(nums[mid]==target){
break;
}
if(nums[mid]<target){
l = mid+1;
}
else{
r = mid-1;
}
}
if(pos==-1||nums[pos]!=target){
return ans;
}
l = 0;r = pos;
while(l<r){
int mid = (l+r)>>1;
if(nums[mid]<target){
l = mid+1;
}
else{
r = mid;
}
}
ans[0] = l;
l = pos;r = nums.length-1;
int res = pos;
while(l<=r){
int mid = (l+r)>>1;
if(nums[mid]==target){
res = mid;
}
if(nums[mid]<=target){
l = mid+1;
}
else{
r = mid-1;
}
}
ans[1] = res;
return ans;
}
}