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

由排序数组可以想到使用二分查找法先查找到一个待查的数字,然后再确定该数字第一次出现的位置和最后一次出现的位置,相减即可得到该数字在排序数组中出现的次数。该方法的时间复杂度为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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值