數字在排序數組中出現的次數(二分查找)

統計一個數字在排序數組中出現的次數。例如:排序數組{1,2,3,3,3,3,4,5},和數字3,由於3在這個數字中出現了4次,因此輸出4。

解法1:順序掃描,統計該數字出現的次數,時間複雜度爲O(n)。

解法2:利用二分查找,找到一個數字,由於該數字可能出現多次,有可能該數字前後都有可能是所找的數字,因此向兩邊順序掃描,找出第一個該數字和最後一個該數字。由於數字在長度爲n的數組中有可能出現O(n)次,所以時間複雜度爲O(n)

這兩種解法在本質上是一樣的。

解法3:更好的利用二分查找,找到第一個該數字的位置,找到最後一個該數字的位置。

二分查找總是用中間的數字與所找的數字K進行比較,如果中間的數字比K小,向後找;如果中間的數字比K大,向前找;如果相等,我們來進行處理。

假設我們要找第一個K,如果中間數字是K,前一個數字不是K,則中間數字就是我們要找的第一次出現的K;如果中間數字是K,前一個數字也是K,說明第一次出現的K在前面,我們繼續向前找。

同樣的方法我們可以找到最後一個K。判斷中間數字是不是最後一個K,可以看中間數字的後一位是不是K,不是K,則中間數字就是最後一個K;後一個數字是K,則繼續向後找。

class Solution {
public:
    int GetFirstK(vector<int>data,int length,int k,int start,int end)
    {
        if(start > end)
            return -1;
        int middleindex = (start + end)/2 ;
        int middledata = data[middleindex];
        
        if(middledata == k)
        {
            if((middleindex > 0 && data[middleindex -1] != k) || middleindex == 0)
                return middleindex;
            else 
                end = middleindex-1;
        }
        else if(middledata > k)
            end = middleindex-1;
        else 
            start = middleindex +1;
        
        return GetFirstK(data,length,k,start,end);
    }
    
    int GetLastK(vector<int>data,int length,int k,int start,int end)
    {
        if(start > end)
            return -1;
        int middleindex = (start + end)/2 ;
        int middledata = data[middleindex];
        
        if(middledata == k)
        {
            if((middleindex < length-1 && data[middleindex +1] != k) || middleindex == length-1)
                return middleindex;
            else 
                start = middleindex+1;
        }
        else if(middledata > k)
            end = middleindex-1;
        else 
            start = middleindex +1;
        
        return GetLastK(data,length,k,start,end);
    }
    
    int GetNumberOfK(vector<int> data ,int k) 
    {
        int number = 0;
        int length = data.size();
        if(length >0)
        {
            int first = GetFirstK(data,length,k,0,length-1);
            int last = GetLastK(data,length,k,0,length-1);
            
            if(first >-1 && last >-1)
                number = last - first +1;
        }
        return number;
    }
};

GetFirstK,GetLastK,都是利用二分查找在數組中查找一個數字,時間複雜度是O(logn),因此總的時間複雜度也是O(logn)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章