37. 数字在排序数组中出现的次数

题目:统计一个数字在排序数组中出现的次数

思路:

1. 从头到尾遍历,超简单,但是应该不符合出题人的意图。

2.因为数组中的数字是整型,所以稍微做一下改变,找 k - 0.5 以及 k + 0.5 的位置(但实际上,数组中是没有 k - 0.5 和 k + 0.5这俩数字的,找 k - 0.5的位置实际上就是第一个 k 出现的位置, 找 k + 0.5 的位置实际上就是第一个k + 1出现的位置)。

例如:对于数组 1 2 2 3,k = 2,找1.5和2.5的位置:

先看1.5:start = 0, end = 3, mid = (0 + 3)/2=1,data[mid] = 2 > 1.5, 则 end = mid - 1 = 0,这时,mid = (0 + 0)/2 = 0, data[mid] = 1 < 1.5, 则start = mid + 1 = 1,这时 start > end, 这个时候的start就是 第一个k出现的位置;

再看2.5:start = 0, end = 3, mid = (0 + 3)/2=1,data[mid] = 2 < 2.5, 则start = mid + 1 = 2,这时,mid = (2 + 3)/2 = 2, data[mid] = 2 < 2.5, 则start = mid + 1 = 3,这时, mid = (3 + 3) / 2 = 3, data[mid] = 3 > 2.5, 则 end = mid - 1 = 2,这时 end < start, 这时的start = 3, 是第一个k + 1,就是3出现的位置;

对于特殊的情况:例如加入数组为1 2 2 2, k = 2, 数组中没有k + 1,即没有3, 那么:自己运行一下可以知道,k + 0.5对应的程序返回的是4,k - 0.5返回的是1,结果就是对的。数组为 2 2 2 3,k = 2的情况类似。

两者相减就是2,即2出现的次数;

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        return Search(data, k + 0.5) - Search(data, k - 0.5);
    }
    int Search(vector<int> data, double k)
    {
        int start = 0, end = data.size() - 1;
        if(start > end)
            return 0;
        while(start <= end)
        {
            int mid = (start + end) >> 1;
            if(data[mid] < k)
                start = mid + 1;
            else
                end = mid - 1;
        }
        return start;
    }
};

3. 找到第一个k出现的位置,找到最后一个k出现的位置,两者相减 再加1 就是k出现的次数

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        if(data.empty())
            return 0;
        int number = 0;
        int first = GetFirstIndex(data,k,0,data.size()-1);
        int last = GetLastIndex(data,k,0,data.size()-1);
        if(first>-1 && last>-1)
            number = last - first +1;
        return number;

    }
    int GetFirstIndex(vector<int> &data,int k,int start,int end){
        if(start > end)
            return -1;
        int mid = start+(end-start)/2;
        if(data[mid] == k){
            if((mid == start) || (data[mid-1] != k))
                return mid;
            else
                end = mid-1;
        }
        else{
            if(data[mid] > k)
                end = mid - 1;
            else
                start = mid + 1;
        }
        return GetFirstIndex(data,k,start,end);
    }
    int GetLastIndex(vector<int> &data,int k,int start,int end){
        if(start > end)
            return -1;
        int mid = start+(end-start)/2;
        if(data[mid]==k){
            if((mid == end) || (data[mid+1] != k))
                return mid;
            else
                start = mid +1;
        }
        else{
            if(data[mid]>k)
                end = mid-1;
            else
                start = mid+1;
        }
        return GetLastIndex(data,k,start,end);
    }
};

4. 利用map

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值