劍指Offer——(37)數字在排序數組中出現的次數

題目描述:

統計一個數字在排序數組中出現的次數。

實現如下:

方法一

//利用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;
    }
};
發佈了107 篇原創文章 · 獲贊 36 · 訪問量 7萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章