Given a sorted array of integers, find the starting and ending position of a given target value.
Your algorithm's runtime complexity must be in the order of O(log n).
If the target is not found in the array, return [-1, -1]
.
For example,
Given [5, 7, 7, 8, 8, 10]
and target value 8,
return [3, 4]
.
二分查找一般都是找到某一个特定的数字,通过比较中间的数值和目标数值的大小(target>mid 目标数值就在右边 target<mid 目标数值就在左边 如果相等就直接返回mid)可以获得目标函数在哪个部分。但是这道题目要求求出目标数字出现的区间(大于等于一个),这就涉及到当找到目标数字时,需要判断目标数字的左右是否还有目标数值,如果有,再在两边搜索,左边有的话就在左边找第一个出现目标数值的index,右边有的话就在右边找最后一个出现目标数值的index,这样我们又想到可以利用递归在左右搜索第一个出现或最后一个出现的目标数值。
int findFirst(vector<int>& nums,int target,int low,int high){
if(low>high) return -1; \\递归到low》high 即所有数列中的数都遍历过没有return 即没有找到目标数值,返回-1
int mid=(low+high)/2;
if(nums[mid]==target){ \\当找到第一个target
if(((mid-1)>=0&&nums[mid-1]!=target)||mid==0) return mid; \\看它左边是否到头或者是否有目标数值,如果有目标数值,则第一个目标数 值在左边,否则为第一个目标数值
else high=mid-1;
}
else if(target<nums[mid]) high=mid-1;
else low=mid+1;
return findFirst(nums,target,low,high);
}
没有找到相等数值的时候就和一般二分查找一样。
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> res;
if(nums.empty()) return res;
int low=0;
int high=nums.size()-1;
int first=findFirst(nums,target,low,high);
int last=findLast(nums,target,first,high);
res.push_back(first);
res.push_back(last);
return res;
}
int findFirst(vector<int>& nums,int target,int low,int high){
if(low>high) return -1;
int mid=(low+high)/2;
if(nums[mid]==target){
if(((mid-1)>=0&&nums[mid-1]!=target)||mid==0) return mid;
else high=mid-1;
}
else if(target<nums[mid]) high=mid-1;
else low=mid+1;
return findFirst(nums,target,low,high);
}
int findLast(vector<int>& nums,int target,int low,int high){
if(low>high) return -1;
int mid=(low+high)/2;
if(nums[mid]==target){
if(((mid+1)<nums.size()&&nums[mid+1]!=target)||mid==nums.size()-1) return mid;
else low=mid+1;
}
else if(target>nums[mid]) low=mid+1;
else high=mid-1;
return findLast(nums,target,low,high);
}
};