一、题目描述:34. 在排序数组中查找元素的第一个和最后一个位置(中等)
给定一个按照升序排列的整数数组 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]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
二、解题思路
有两种思路
1、二分查找先找到最左边界,再找到最右边界。
2、二分查找到target,再从target开始分别二分查找最左边界和最右边界(本次代码使用方法2,有点啰嗦)
三、代码
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size() == 0)
return vector<int>(2,-1);
int left = 0,right = nums.size()-1;
int mid = 0;
vector<int> out;
while(left < right)
{
mid = (left+right)/2;
if(nums[mid] == target)
{
int left1 = left,right1 = mid;
int left2 = mid,right2 = right;
while(nums[left1] != target && left1 < right1)
{
int mid1 = (left1 + right1)/2;
if(mid1 == 0 )
{
if(nums[mid1] == target)
{
left1 = mid1;
}
else{
left1 = right1;
}
break;
}
if(nums[mid1] == target && mid1> 0 && nums[mid1 -1] != target)
{
left1 = mid1;
left = mid1;
break;
}
else if(nums[mid1] == target && mid1 > 0 && nums[mid1-1] == target)
{
right1 = mid1 -1;
}
else
{
left1 = mid1 + 1;
}
}
left = left1;
while(nums[right2] != target && left2 < right2)
{
cout<<"right="<<right2<<endl;
cout<<"nums[right2]="<<right2<<endl;
int mid1 = (left2 + right2)/2;
if(mid1 == nums.size()-1 )
{
if(nums[mid1] == target)
{
right2 = mid1;
}
else{
right2 = left2;
}
break;
}
if(nums[mid1] == target && mid1 < nums.size()-1 && nums[mid1 +1] != target)
{
right2 = mid1;
right = mid1;
//cout<<"right="<<right2<<endl;
//cout<<"nums[right2]="<<right2<<endl;
break;
}
else if(nums[mid1] == target && mid1 < nums.size() -1 && nums[mid1+1] == target)
{
left2 = mid1 +1;
}
else
{
right2 = mid1 - 1;
// cout<<"right="<<right2<<endl;
// cout<<"nums[right2]="<<right2<<endl;
}
}
right = right2;
break;
}
if(nums[mid] < target)
left = mid + 1;
else
right = mid -1;
}
if (left < 0 || right > nums.size() -1 || (nums[left] != target && nums[right] != target))
{
out.push_back(-1);
out.push_back(-1);
return out;
}
out.push_back(left);
out.push_back(right);
return out;
}
};