文章目录
题目
方法一:二分查找(先找到mid,在根据mid确定左右区间)
- 第一步先找到target所在的位置mid
- 在根据mid 在数组左右分两个while循环找左右区间,一旦nums[mid] != target,就返回mid值
- 最后查找位置会停在区间外的一个位置,需要矫正回来
java
// 方法一 :二分法找目标元素的位置,然后在目标元素的位置的左右找左右区间
public int[] searchRange(int[] nums, int target) {
if(nums.length == 0) return new int[]{-1,-1};
int mid = search( nums, target);//二分法找target位置
if(mid == -1) return new int[]{-1,-1};//若没有 直接返回 - 1 - 1
int m = mid;
while(m < nums.length){//根据mid 去找右区间最大下标
if(nums[m] != target) break;
m ++;
}
int n = mid;
while(n >=0){//根据mid 去找左区间最小下标
if(nums[n] != target) break;
n--;
}
return new int[]{n+1,m-1};//最终m其实是在右区间后面一个位置停止的 m需要-1 同理最终实是在左区间前面一个位置停止的,n需要+1
}
//二分法找目标元素 目标元素不存在返回 - 1
public int search(int[] nums, int target){
int left = 0 ;
int right = nums.length - 1 ;
while(left <= right){
int mid = (right - left)/2 + left;
if(nums[mid] == target) return mid;
if(nums[mid] > target) right = mid -1;
if(nums[mid] < target) left = mid +1;
}
return -1;
}
方法二:分两次二分查找,一次用于找左区间,一次用于找右区间
一定要结合画图来理解
java
// 方法二 :二分法来去寻找左右边界
public int[] searchRange(int[] nums, int target) {
if(nums.length == 0) return new int[]{-1,-1};
int left = leftjoin(nums,target);
int right = rightjoin(nums,target);
// 情况一
if (left == -2 || right == -2) return new int[]{-1, -1};
// 情况三
if (right - left > 1) return new int[]{left + 1, right - 1};
// 情况二
return new int[]{-1, -1};
}
//寻找左边界
public int leftjoin(int[] nums, int target){
int left = 0;
int right = nums.length -1;
int leftjoin = -2;//记录左边界的赋值情况
while(left <= right){
int mid = left + (right -left);
if(nums[mid] >= target){
right = mid -1;
leftjoin = right;
}else {
left = mid + 1;
}
}
return leftjoin;
}
//寻找右边界
public int rightjoin(int[] nums, int target){
int left = 0;
int right = nums.length -1;
int rightjoin = -2;//记录左边界的赋值情况
while(left <= right){
int mid = left + (right -left);
if(nums[mid] > target){
right = mid -1;
}else {
left = mid + 1;
rightjoin = left;
}
}
return rightjoin;
}