emmm,这是个悲伤的故事,先上题:
刚开始打算直接暴力枚举,然后看到算法时间复杂度,一看这复杂度就和二分查找很配,然后就打算进行两次二分查找确定具体边界,然后就超时,这是超时代码1号:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0) return {-1,-1};
int left=0;
int right=nums.size()-1;
int start;
int end;
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]>=target)
right=mid;
else left=mid+1;
}
if(nums[left]!=target)
return{-1,-1};
start=left;
left=0;
right=nums.size()-1;
while(left<right)
{
int mid=left+(right-left)/2;
if(nums[mid]<=target)
left=mid;
else right=mid-1;
}
if(nums[right]!=target)
return{-1,-1};
end=right;
return {start,end};
}
};
然后就很疑惑的看向了题解区,然后我发现有个大佬也是这样想的超激动 然后粗略一看,发现了mid的计算方式不一样,然后就觉得,嗯一定是这个问题,然后就出现了超时代码2号(这是可以过测试用例的,但是也只能过测试用例):
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.size()==0) return {-1,-1};
int left=0;
int right=nums.size()-1;
while(left<right)
{
int mid=(left+right+1)>>1;
if(nums[mid]>=target)
right=mid;
else left=mid+1;
}
if(nums[left]!=target)
return{-1,-1};
int start=left;
left=0;
right=nums.size()-1;
while(left<right)
{
int mid=(left+right+1)>>1;
if(nums[mid]<=target)
left=mid;
else right=mid-1;
}
if(nums[right]!=target)
return{-1,-1};
int end=right;
return {start,end};
}
};
再然后,我借鉴剽窃了大佬的代码交上去,大佬果然是大佬,代码如下:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if(nums.empty()) return {-1,-1};
int left=0;
int right=nums.size()-1;
while(left<right){
int mid=(left+right)>>1;
if(nums[mid]>=target){
right=mid;
}
else{
left=mid+1;
}
}
if(nums[left]!=target) return {-1,-1};
int start=left;
left=0;
right=nums.size()-1;
while(left<right){
int mid=(left+right+1)>>1;
if(nums[mid]<=target){
left=mid;
}
else{
right=mid-1;
}
}
if(nums[left]!=target) return {-1,-1};
int end=right;
return {start,end};
}
};
作者:TeFuirnever
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/solution/shou-hui-man-hua-tu-jie-leetcodezhi-zai-pai-xu-shu/
来源:力扣(LeetCode)
大佬的题解里还有漫画讲解,超棒的(但是我还是看不出来我的代码时间上是差在了哪,我感觉我的和大佬的就是一样的 )