剑指Offer——(37)数字在排序数组中出现的次数

来源:互联网 发布:网络外教一对一价格 编辑:程序博客网 时间:2024/06/14 23:29

题目描述:

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

实现如下:

方法一

//利用count计数,时间复杂度O(n)class Solution {public:    int GetNumberOfK(vector<int> data, int k)     {        return count(data.begin(), data.end(), k);    }};

方法二

//从头开始遍历,时间复杂度O(n)class Solution {public:    int GetNumberOfK(vector<int> data, int k)     {        int count = 0;        for (int i = 0; i < data.size(); ++i)        {            if (data[i] == k)                ++count;        }        return count;    }};

方法三

//因为是在排序数组中寻找,所以可以利用二分查找算法//通过查找第一个k值元素的下标和最后一个k值元素的下标,求出个数//时间复杂度O(logn)class Solution {public:    //寻找第一个k值元素的下标    int FirstKIndex(vector<int>& data, int k, int left, int right)    {        if (left > right)//防御性动作            return -1;        int middleIndex = (right - left) / 2 + left;//防止值溢出        int middleValue = data[middleIndex];//获取中位数的值        if (middleValue == k)//如果中位数与k相等,则将中位数的前一个数与k比较        {            //如果中位数的前一个数不等于k或中位数就是下标0元素,此时中位数的下标就是第一个k值元素的下标            if ((middleIndex > 0 && data[middleIndex - 1] != k) || middleIndex == 0)                return middleIndex;            else//若相等,就继续寻找                right = middleIndex - 1;        }        else if (middleValue > k)//如果中位数大于k,则说明第一个k值元素在中位数的前面            right = middleIndex - 1;        else//如果中位数小于k,则说明第一个k值元素在中位数的后面            left = middleIndex + 1;        return FirstKIndex(data, k, left, right);//递归继续寻找    }    //寻找最后一个k值元素的下标    int LastKIndex(vector<int>& data, int k, int left, int right)    {        if (left > right)//防御性动作            return -1;        int middleIndex = (right - left) / 2 + left;        int middleValue = data[middleIndex];        if (middleValue == k)//如果中位数与k相等,则将中位数的后一个数与k比较        {            //如果中位数的后一个数不等于k或中位数就是数组中的最后一个元素,此时中位数的下标就是最后一个k值元素的下标            if ((middleIndex < data.size() - 1 && data[middleIndex + 1] != k) || middleIndex == data.size() - 1)                return middleIndex;            else//若相等,就继续寻找                left = middleIndex + 1;        }        else if (middleValue > k)//如果中位数大于k,则说明最后一个k值元素在中位数的前面            right = middleIndex - 1;        else//如果中位数小于k,则说明最后一个k值元素在中位数的后面            left = middleIndex + 1;        return LastKIndex(data, k, left, right);//递归继续寻找    }    int GetNumberOfK(vector<int> data, int k)    {        int num = 0;        if (data.empty()) return 0;        int first = FirstKIndex(data, k, 0, data.size() - 1);//获取第一个k值元素的下标        int last = LastKIndex(data, k, 0, data.size() - 1);//获取最后一个k值元素的下标        if (first > -1 && last > -1)            num = last - first + 1;计算k值元素个数        return num;    }};
阅读全文
0 0
原创粉丝点击