剑指OFFER题33------按牛客网热度排序
时间:2018.12.12.2058
作者:Waitt
题目
统计一个数字在排序数组中出现的次数。
时间限制:1秒 空间限制:32768K 热度指数:173408
解答
1、顺序遍历
顺序扫描一遍数组,统计该数字出现的次数。
2、二分查找
假设我们需要找的数字是k,那么就需要找到数组中的第一个k和最后一个k出现的位置。
如何通过二分查找得到第一个k的位置呢?
取数组中间的数字与k作比较,
如果该数字比k大,那么k只能出现在前半部分,那么下一轮只能在前半部分找;
如果该数字比k小,那么k只能出现在后半部分,那么下一轮只能在后半部分找;
如果该数字等于k,需要判断这是不是第一个k,如果该数字的前一个数字不是k,那么该数字就是第一个k,否则需要在前半部分继续寻找第一个k;
寻找最后一个k的方法与寻找第一个k的方法一样。
class Solution {
public:
int getlow(vector<int> data, int s, int e,int k)//获取下限
{
int m=(s+e)/2;
while(s<=e) //s==e时仍需循环,才可遍历完所有数据
{
if(data[m]==k)
{
if(m==s||data[m-1]!=k)
return m;
e=m-1;
}
if(data[m]<k)
{
s=m+1;
}
if(data[m]>k)
{
e=m-1;
}
m=(s+e)/2;
}
return -1;//此时则说明无法在数组中找到k
}
int getup(vector<int> data, int s, int e,int k)//获取上限
{
int m=(s+e)/2;
while(s<=e) //s==e时仍需循环,才可遍历完所有数据
{
if(data[m]==k)
{
if(m==e||data[m+1]!=k)
return m;
s=m+1;
}
if(data[m]<k)
{
s=m+1;
}
if(data[m]>k)
{
e=m-1;
}
m=(s+e)/2;
}
return -2;//此时则说明无法在数组中找到k
}
int GetNumberOfK(vector<int> data ,int k) {
if(data.empty())
return 0;
int n=data.size()-1;
int lowe=getlow(data,0,n,k);
int upe=getup(data,0,n,k);
return upe-lowe+1;
}
};