您的位置:首页 > Web前端

《剑指offer》——数字在排序数组中出现的次数

2016-01-22 19:39 441 查看
由排序数组可以想到使用二分查找法先查找到一个待查的数字,然后再确定该数字第一次出现的位置和最后一次出现的位置,相减即可得到该数字在排序数组中出现的次数。该方法的时间复杂度为o(logn)







/*k第一次出现的下标*/
int GetFirstK(vector<int> data, int lo, int hi, int k)
{
if(hi < lo)//如果k不存在该数组中,则返回-1
return -1;
int mi = lo + (hi - lo) / 2;
if(data[mi] == k)//如果data[mi]等于k
{
//如果mi大于0且mi前一个位置上的数字不为k,或者mi等于0
if(mi > 0 && data[mi - 1] != k || mi == 0)
return mi;//mi即为k第一次出现的下标
else
hi = mi - 1;//如果mi前一个位置上的数字仍为k,则在数组的前半段查找k
}
else if(k < data[mi])//如果k在data[mi]之前,则在数组的前半段查找k
hi = mi - 1;
else
lo = mi + 1;//如果k在data[mi]之后,则在数组的后半段查找k
return GetFirstK(data, lo, hi, k);//继续查找k第一次出现的下标
}

/*k最后一次出现的下标*/
int GetLastK(vector<int> data, int lo, int hi, int k)
{
if(hi < lo)//如果k不存在该数组中,则返回-1
return -1;
int mi = lo + (hi - lo) / 2;
if(data[mi] == k)//如果data[mi]等于k
{
//如果mi小于数组的最大下标且mi后一个位置上的数字不为k,或者mi等于数组的最大下标
if(mi < data.size() - 1 && data[mi + 1] != k || mi == data.size() - 1)
return mi;//mi即为k第一次出现的下标
else
lo = mi + 1;/如果mi后一个位置上的数字仍为k,则在数组的后半段查找k
}
else if(data[mi] < k)//如果k在data[mi]之后,则在数组的后半段查找
lo = mi + 1;
else
hi = mi - 1;//如果k在data[mi]之前,则在数组的前半段查找
return GetLastK(data, lo, hi, k);//继续查找k最后一次出现的下标
}

/*k在数组中出现的次数*/
int GetNumberOfK(vector<int> data ,int k)
{
int num = 0;
if(data.empty())//如果数组为空,则返回0
return num;
int lo = 0, hi = data.size() - 1;
int fi = GetFirstK(data, lo, hi, k);
int la = GetLastK(data, lo, hi, k);
if(fi > -1 && la > -1)//如果k存在数组中,则返回k出现的次数
num = la - fi + 1;
return num;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: