题目:
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
示例1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]示例2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
解题思路:
用两次二分查找法,分别确定左边界和右边界
class Solution {
public:
//二分查找法
vector<int> searchRange(vector<int>& nums, int target) {
int n=nums.size();//计算数组长度
int left=0;//左指针从下标为0的位置开始
int right=n-1;//右指针从最后一个下标开始
vector<int> res(2,-1);//定义一个大小为2的数组,初始化为-1
if(n==0||nums[0]>target) return res;//如果nums为空,则直接返回[-1,-1]
//先确定左边界
while(left<right)
{
//除以2向下取整(0+5/2=2)
int mid=(left+right)>>1;//找中位数
if(nums[mid]>=target)//如果中位数大于等于target
{
right= mid;//将right移动到mid的位置
}
//中位数小于target
else
{
left=mid+1;//left移动到mid的后一个位置
}
}
//如果循环结束后,right所在位置的值不为target,说明数组中没有target,直接返回res
if(nums[right]!=target) return res;
//若不是上面的情况,那么就将res[0]的值更新为right
res[0]=right;//左边界已经找到
left=0;
right=n-1;
//接下来确定右边界
while(left<right)
{
//除以2还要向上取整(0+5+1/2=3)
int mid=left+right+1>>1;
if(nums[mid]<=target)//中位数小于等于target
{
left= mid;//将left移动到mid的位置
}
//大于target
else
{
right=mid-1;//right移动到mid的前一个
}
}
//更新右边界的下标值
res[1]=left;
//返回这个res数组
return res;
}
};