题目描述
统计一个数字在排序数组中出现的次数。
方法一:最简单粗暴的方法就是遍历!等于k就令count+1。这个方法是时间复杂度是O(n)。
class Solution{
public:
int GetNumberOfK(vector<int> data,int k){
if(data.size()<0)
return 0;
int count=0;
for(int i=0;i<data.size();i++)
{
if(data[i]==k)
count++;
}
return count;
}
};
方法二:二分法!有人说看到有序数组就要想到二分法!
用二分法找到这个数第一次出现和最后一次出现的下标。二分法的时间复杂度是O(logn)
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
return getlast(data,k)-getfirst(data,k)+1;
}
int getfirst(vector<int> data,int k){
int start=0,end=data.size()-1;
int mid;
while(start<=end){
mid=(start+end)/2;
if(data[mid]<k)
start=mid+1;
else
end=mid-1;
}
return start;
}
int getlast(vector<int> data,int k){
int start=0,end=data.size()-1;
int mid;
while(start<=end){
mid=(start+end)/2;
if(data[mid]<=k)
start=mid+1;
else
end=mid-1;
}
return end;
}
};
方法三:同样是基于二分法的思想,但是想法更加巧妙(这个方法是讨论区里的大神写的,也一起总结到这里)
因为数组中的数是整数,所以加减0.5后,这个数可以插入到数组中的哪个位置,然后相减
class Solution{
public:
int GetNumberOfK(vector<int> data,int k){
return find(data,k+0.5)-find(data,k-0.5);
}
int find(const vector<int> data,double num)
{
int start=0,end=data.size()-1;
while(start<=end)
{
int mid=(start+end)/2;
if(data[mid]<num)
start=mid+1;
else
end=mid-1;
}
return start;
}
};