方法一:

  • 暴力,从头开始找到第一个值为k的元素,再计算连续的k的个数即可。缺点:没有利用好有序数组的特性。

代码如下:

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int ans;
        for(int i=0;i<data.size();i++){
            if(data[i]==k){
                int j=i+1;
                //从第一个为k的元素起,找到第一个不为k的元素止。
                while(j<data.size()&&data[j]==k)
                    j++;
                return j-i;
            }
        }
        return 0;
    }
};

复杂度分析:

时间复杂度:O(n),最坏情况,k在数组末尾,需要n次for循环。
空间复杂度:O(1),常数个临时变量。

方法二:

  • 利用数组有序的特征,考虑使用二分法
  • 二分法找到值为k的元素,然后再寻找附近连续的k的个数。

图解如下:

图片说明

代码如下:

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int ans;
        int left=0,right=data.size()-1,mid;
        while(left<=right){
            //二分法寻找等于k的值。
            mid=(left+right)/2;
            if(data[mid]<k){
                left=mid+1;
            }
            else if(data[mid]>k){
                right=mid-1;
            }
            else{
                //找到mid附近值都等于k的数目。
                int i=mid-1,j=mid+1;
                //此处的while循环的判断条件也可以是i>=left,j<=right,不过执行起来两者并没有区别。
                while(i>=0&&data[i]==k)
                    i--;
                while(j<=data.size()-1&&data[j]==k)
                    j++;
                return j-i-1;
            }
        }
        return 0;
    }
};

复杂度分析:

时间复杂度:O(n),二分法找到等于k的数是O(logn),还受到k的数量的影响,最坏情况下全部为k则需要O(n)。
空间复杂度:O(1),常数个临时变量。