一.题目描述
NC74数字在升序数组中出现的次数
题目链接:
https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=188&&tqId=38596&rp=1&ru=/activity/oj&qru=/ta/job-code-high-week/question-ranking
统计一个数字在升序数组中出现的次数。
二.算法(模拟)
要求数字在有序数组中出现的次数,那么直接遍历一遍数组是不是就是可以了??下面是通过的代码:

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int ans=0;
        for(int i=0;i<data.size();i++){
            if(data[i]==k){
                ans++;
            }
        }
        return ans;
    }
};

时间复杂度:o(n)
空间复杂度:o(1) 没有利用额外的空间
优缺点:时间复杂度对于该题来说还是比较高,但是实现简单。
三.算法(二分)
图片说明
暴力的方法无法将数组有序的条件利用上,因为数组是升序的,目标值如果有多个就是连在一起的,因此我们可以查找目标值的范围即:上界和下界。
下界:如果存在目标值,则指向第一个目标值,否则,如果不存在,则指向大于目标值的第一个值。
上界:不管目标值存在与否,都指向大于目标值的第一个值。
下面给出完整代码:

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int n=data.size();
        int l=0;
        int r=n;
        int ans=0;
        // 找到升序序列中的下界
        while(l<r){
            int mid=(l+r)/2;
            if(data[mid]<k)
                l=mid+1;
            else
                r=mid;
        }
        int left=l;
        // 找到升序序列中的上界
        l=0;
        r=n;
        while(l<r){
            int mid=(l+r)/2;
            if(data[mid]<=k)
                l=mid+1;
            else
                r=mid;
        }
        int right=l;
        //上界减去下界为数字在升序数组出现的次数
        return right-left;
    }
};

时间复杂度:o(logn)
空间复杂度:o(1) 没有利用额外的空间
优缺点:时间复杂度低,但是实现起来没有算法二简洁