题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
算法思路
二分法,在左右子树中找到比left_index小和比right_index大的和target相等的元素下标。
特殊情况:当nums中所有元素相等时,如果依然按照二分法递归来做会出现内存超过限制的问题。解决办法是先判断head和tail两个指针指向的位置是否相等,如果相等说明这两个指针指向的位置区间内所有元素相等,再判断这些元素是否和target相等即可。
C++代码
class Solution {
public:
void compare(int &left_index, int &right_index, int index){
if(index < left_index){
left_index = index;
}
if(index > right_index){
right_index = index;
}
}
void searchFunc(vector<int> nums, int &left_index, int &right_index, int head, int tail, int target){
int mid = (head + tail)/2;
if(nums[mid] == target){
compare(left_index, right_index, mid);
}
if(head >= tail) return;
if(nums[head] == nums[tail]){
if(nums[head] == target){
compare(left_index, right_index, head);
compare(left_index, right_index, tail);
return;
}
else{
return;
}
}
if(nums[head] == target){
compare(left_index, right_index, head);
}
if(nums[tail] == target){
compare(left_index, right_index, tail);
}
searchFunc(nums, left_index, right_index, head, mid, target);
searchFunc(nums, left_index, right_index, mid+1, tail, target);
}
vector<int> searchRange(vector<int>& nums, int target) {
int len=nums.size();
vector<int> res;
if(len < 1){
res.push_back(-1);
res.push_back(-1);
return res;
}
int head=0, tail=len-1, mid = (head + tail)/2;
int left_index=len, right_index=-1;
searchFunc(nums, left_index, right_index, 0, mid, target);
searchFunc(nums, left_index, right_index, mid+1, len-1, target);
if(left_index == len){
left_index = -1;
}
res.push_back(left_index);
res.push_back(right_index);
return res;
}
};