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

本文介绍了一种高效的方法来统计一个数字在已排序数组中出现的次数,通过二分查找确定目标值首次和末次出现的位置,进而计算其出现次数。此外,还提供了利用STL中的lower_bound和upper_bound函数实现的简洁代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

统计一个数字在排序数组中出现的次数。

一、二分查找思想

1.找到第一个k出现的位置,先二分查找入手,如果相等了,则向前一个寻找是否等于k,如果不相等则直接返回位置,即为第一个出现的位置,如果相等了,那么向左侧缩小范围,right的值变为前一个位置,继续递归查找。

2.找到最后一个k出现的位置,同上方法,只不过是若后一个等于k,则向右侧缩小,left等于后一个位置,继续递归查找。

3.二分查找的思想,能够准确无误地写出无bug的二分查找,关键点在于下标的选取while(left<=right),此时right取到数组n-1处left和right后面的变换都应该取middle-1和middle+1进行。

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int len = data.size();
        if(len == 0) return 0;
        int number = 0;
        int first = getFirstK(data, len, k, 0, len-1);
        int last = getLastK(data, len, k, 0, len-1);
        if(first > -1 && last > -1)
            number = last - first + 1;
        return number;
    }
    int getFirstK(vector<int> data, int len, int k, int left, int right) {
        if(left > right) return -1;
        int middle = left + ((right - left) >> 1);
        if(data[middle] == k) {
            if((middle > 0 && data[middle-1] != k) || middle == 0)
                return middle;
            else
                right = middle - 1;  //如果前一个数仍为k,那么就进一步缩小搜索范围,限定在前半部分[left,middled-1]
        }
        else if(data[middle] > k)
            right = middle - 1;
        else
            left = middle + 1;
        return getFirstK(data, len, k, left, right);  //递归调用,直到找到第一个K为止
    }
    int getLastK(vector<int> data, int len, int k, int left, int right) {
        if(left > right) return -1;
        int middle = left + ((right - left) >> 1);
        if(data[middle] == k) {
            if((middle < len - 1 && data[middle+1] != k) || middle == len - 1)
                return middle;
            else
                left = middle + 1; //这里是后半部分,限定在[middle+1, right]之间
        }
        else if(data[middle] > k)
            right = middle - 1;  //这里前后两部分通用的
        else
            left = middle + 1;
        return getLastK(data, len, k, left, right);
    }
};


二、使用STL

1.lower_bound返回第一个不小于目标数的迭代器(the value pointed by the iterator returned by this function may also be equivalent to val)

2.upper_bound返回第一个一个大于目标数的迭代器(the value pointed by the iterator returned by this function cannot be equivalent to val, only greater)

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        std::vector<int>::iterator low,up;
        low = lower_bound(data.begin(), data.end(), k);
        up = upper_bound(data.begin(),data.end(), k);
        return up - low;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值