34. 在排序数组中查找元素的第一个和最后一个位置
2023版
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = { -1, -1 };
if(nums.length == 0)
return res;
int l = 0;
int r = nums.length - 1;
// 求第一个出现的 target
while(l < r)
{
int m = l + r >> 1;
if(target <= nums[m])//小于等于
r = m;//左滑
else
l = m+1;
}
if(nums[l] != target)
return res;
res[0] = l;
l = 0;
r = nums.length-1;
// 求最后一个出现的target
while(l < r)
{
int m = l + r + 1 >> 1;
if(target >= nums[m])//大于等于
l = m;//右滑
else
r = m -1;
}
res[1] = l;
return res;
}
}
2022版
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res = {-1,-1};
if(nums.length==0){
return res;
}
// 要查询的值 x
int x = target;
// 要查询的源数组
int[] arr = nums;
int l = 0, r = arr.length - 1;
// 明确需求,找x的左边界
// 从右往左查,等于 就一直滑,直到第一个小于 x 的值的时候就退出
while (l < r) {
int mid = l + r >> 1;
// 只要中值点的值 >= x,就一直把右边界移到中值点处
if (arr[mid] >= x)
r = mid;
else
l = mid + 1;
}
if (arr[l] != x){
return res;
}
else {
res[0] = l;
l = 0;
r = arr.length - 1;
// 明确需求,找x的右边界
// 从左向右查,等于 就一直向右滑,直到碰见第一个大于 x 的值
while (l < r) {
// 例 : l + 1 = R
// mid = (l + R) / 2 = l , 而 更新边界的方式是 l = mid ,避免死循环必须 +1
// 这里多了 + 1 就是为了 mid 能走到 l+1 的地方,因为整除是向下取整的
int mid = l + r + 1 >> 1;
// 只要arr[mid] <= x 成立,直到arr[mid] 大于x
if (arr[mid] <= x)
l = mid;
else
r = mid - 1;
}
res[1] = r;
}
return res;
}
}