在排序数组中查找元素的第一个和最后一个位置
分析:有序数组,搜索一个数的左右边界
让搜索区间两边闭合,right取nums.length-1,while的终止条件是left==right+1,其中
应该用<=
public int LeftSearch(int []nums,int target)
{
int left=0;int right=nums.length-1;
while(left<=right)
{
int mid=left+(right-left)/2;
}
}
二分如何能搜索左边界?
关键在于对nums[mid]==target的处理,找到target时不要立即返回,而是缩小搜索区间的上界right,在区间[left,mid)中继续搜索,即不断向左收缩,达到锁定左边界的目的
if(nums[mid]<target)
left=mid+1;
else if(nums[mid[>target)
right=mid-1;
else if(nums[mid]==target)
right=mid-1;
while的退出条件是left==right+1,所以当target比nums中所有元素都大时,会存在以下情况使得索引越界,所以不能直接返回,要检查越界的情况
if(left>=num.length||nums[left]!=target)
return -1;
寻找右边界也是同理
当 nums[mid] == target 时,不要立即返回,而是增大「搜索区间」的下界 left,使得区间不断向右收缩,达到锁定右侧边界的目的。
代码:
class Solution {
public int[] searchRange(int[] nums, int target) {
//二分查找
int leftposition= LeftSearch(nums,target);
if(leftposition==-1)
return new int[]{-1,-1};
int rightpodition=RightSearch(nums,target);
if(rightpodition==-1)
return new int[]{-1,-1};
return new int[]{leftposition,rightpodition};
}
public int LeftSearch(int[] nums,int target)
{
int left=0;
int right=nums.length-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(nums[mid]<target)
{
left=mid+1;
}
else if(nums[mid]>target)
{
right=mid-1;
}
else if(nums[mid]==target)
{
right=mid-1;
}
}
if (left >= nums.length || nums[left] != target)
return -1;
return left;
}
public int RightSearch(int[] nums,int target)
{
int left=0;
int right=nums.length-1;
while(left<=right)
{
int mid=left+(right-left)/2;
if(nums[mid]<target)
{
left=mid+1;
}
else if(nums[mid]>target)
{
right=mid-1;
}
else if(nums[mid]==target)
{
left=mid+1;
}
}
if (right < 0 || nums[right] != target)
return -1;
return right;
}
}