方法一
实现思路
由于在本题中有重复元素的存在,不能直接使用二分查找
先使用map统计了下每一个元素出现的次数,然后利用set构造了没有重复元素的vector数组,在该数组中进行二分查找,当查找到该元素后,利用map数组中存储的数据,实际计算出数据出现的范围,然后返回结果;当没有找到时,直接返回[-1,-1]
主要思想是二分查找框架上的小拓展
实现代码
class Solution {
private:
map<int,int> cnt;
public:
void get_begin_end(int index,vector<int> &nn,vector<int> &re){
int sum=0;
for(int i=0;i<index;i++){
sum+=cnt[nn[i]];
}
re[0]=sum;
re[1]=sum+cnt[nn[index]]-1;
}
vector<int> searchRange(vector<int>& nums, int target) {
//统计数据
for(auto i:nums){
if(!cnt.count(i))
cnt[i]=1;
else cnt[i]++;
}
set<int> t(nums.begin(),nums.end());
vector<int> nn(t.begin(),t.end());
sort(nn.begin(),nn.end());
int begin=0,end=nn.size()-1;
vector<int> re(2,-1);
while(begin<=end){
int mid=(begin+end)/2;
if(target==nn[mid]){
get_begin_end(mid,nn,re);
return re;
}
else if(target<nn[mid]){
end=mid-1;
}
else if(target>nn[mid]){
begin=mid+1;
}
}
return re;
}
};
提交结果
时间复杂度O(n)
方法二
实现思路
找到区间的左端点和区间的右断点,根据小特性获取
总结
我的第一种方法实际上有点用空间换时间,所以在查找之前先进行了map的赋值,
第二张方法是按照查找左右端点的思想,所以需要进行两次二分查找