經(jīng)典面試題16 - 數(shù)組中出現(xiàn)次數(shù)超過一半的數(shù)字

問題
數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,請找出這個數(shù)字。

例如: 輸入一個長度為7的數(shù)組,

{1,2,2,2,5,4,2}

由于數(shù)字2在數(shù)組中出現(xiàn)了4次,超過數(shù)組長度的一半,因此輸出2。如果不存在則輸出0。

解答

首先說這是一道很經(jīng)典的面試題,很多互聯(lián)網(wǎng)公司都曾經(jīng)采用過這個題目。

下面是對該題的分析思路:

  • 如果沒有時間復雜度的要求, 我們可以對數(shù)組進行排序,排序后的數(shù)組,那么我們只要遍歷一次就可以統(tǒng)計出每個數(shù)字出現(xiàn)的次數(shù),這樣也就能找出符合要求的數(shù)字。按照這個思路的時間復雜度是O(nlogn), 其中排序的時間復雜度是O(nlogn),遍歷的時間復雜度O(n)。

  • 另一個思路是我們可以創(chuàng)建一個哈希表來消除排序的時間。哈希表的鍵值為數(shù)組中的數(shù)字,值為該數(shù)字對應的次數(shù)。有了這個哈希表之后,我們只需要遍歷數(shù)組中的每個數(shù)字,找到它在哈希表中對應的位置并增加它出現(xiàn)的次數(shù)。這種哈希表的方法在數(shù)組的所有數(shù)字都在一個比較窄的范圍內(nèi)的時候很有效。

  • 最佳思路:數(shù)組中有一個數(shù)字出現(xiàn)的次數(shù)超過數(shù)組長度的一半,也就是說它出現(xiàn)的次數(shù)比其他所有數(shù)字出現(xiàn)次數(shù)的和還要多。
    因此我們可以考慮在遍歷數(shù)組的時候保存兩個值:一個是數(shù)組中的一個數(shù)字,一個是次數(shù)。當我們遍歷到下一個數(shù)字的時候,如果下一個數(shù)字和我們之前保存的數(shù)字相同,則次數(shù)加1;如果下一個數(shù)字和我們之前保存的數(shù)字不同,則次數(shù)減1。
    如果次數(shù)為0,我們需要保存下一個數(shù)字,并把次數(shù)置1。因為次數(shù)為0,表示前面是字符串計數(shù)抵消為0。

//Java源碼
public int MoreThanHalfNum_Solution(int [] numbers) {
        int maxNum = 0;
        if(numbers.length==0)
            return maxNum;
        maxNum = numbers[0];
        int numCount = 1;
        for(int i=1;i<numbers.length-1;i++){
            if(numbers[i] == maxNum){
                numCount++;
            }else{
                numCount--;
                if(numCount == 0){
                    numCount = 1;
                    maxNum = numbers[i];
                }
            }
        }
        int total = 0;  
        for (int i = 0; i < numbers.length; i++) {  
            if (numbers[i] == maxNum) total++;  
        }  
        if (total * 2 <= numbers.length) {  
            return 0;
        }  
        else return maxNum ;
    }

上述源碼可以在 這里 調(diào)試

推薦閱讀

經(jīng)典面試100題 - 持續(xù)更新中

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容