难度中等1661收藏分享切换为英文接收动态反馈
给定一个按照升序排列的整数数组 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]
示例 3:
输入:nums = [], target = 0 输出:[-1,-1]
提示:
0 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
是一个非递减数组-109 <= target <= 109
通过次数525,745提交次数1,245,076
题解:如果不使用二分法,使用双指针的话,思路会很简单,一个从前往后遍历,一个从后往前遍历,找到即可。但是题目要求使用二分法,那就折半查找,如果元素个数小于4的时候,可能直接遍历更简单一些。
代码中包含了注释,就是调试过程中遇到的坑。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ret;
//分为两步,第一步寻找开始位置,第二步寻找结束位置
int reti=-1;
int begin=0,end=nums.size()-1;//mid=nums.size()/2;
while(begin<=end)
{
int mid = begin+(end-begin)/2;
// 判断条件要考虑边界
if((mid!=0 && nums[mid]==target && nums[max(mid-1,0)]<target) || (mid==0 &&nums[mid]==target))
{
reti=mid;
break;
}
else if(nums[mid]<target) //求下界的时候是小于
{
begin=mid+1;
}
else
{
end=mid-1;
}
}
ret.push_back(reti);
reti=-1;
begin=0,end=nums.size()-1;//mid=nums.size()/2;
while(begin<=end)
{
int mid = begin+(end-begin)/2;
if((mid!= nums.size()-1 && nums[mid]==target && nums[mid+1>nums.size()-1?nums.size()-1:mid+1]>target)|| (mid==nums.size()-1 && nums[mid]==target) )
{
reti=mid;
break;
}
else if(nums[mid]<=target) //求上界的时候,这里是小于等于
{
begin=mid+1;
}
else
{
end=mid-1;
}
}
ret.push_back(reti);
return ret;
}
};
执行结果:
通过
显示详情
添加备注
执行用时:8 ms, 在所有 C++ 提交中击败了58.21%的用户
内存消耗:13.2 MB, 在所有 C++ 提交中击败了70.53%的用户
通过测试用例:88 / 88