劍指offer——數組種出現次數超過一半的數字

題目描述

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。

解析:

一種很常規的思路是排序,排過序後,從首元素開始遍歷數組,用一個整型變量times記錄次數,一個整型變量記temp錄正在判斷的數字,如果遍歷到的數字和正在判斷的數字相同,times加1,否則,times就達到了前者出現的最大次數,判斷它是否符合條件,如果符合,返回這個元素,如果不符合,就將times置1,temp置爲當前遍歷到的數字,直到遍歷結束,但要注意數組長度爲1和爲0的特殊情況。當然這個方法不太好,因爲時間複雜度爲O(nlogn),而本題是存在時間複雜度爲O(n)的解法的。

import java.util.Arrays;
public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array.length == 0 || array == null){
            return 0;
        }
        if(array.length == 1){
            return array[0];
        }
        //調用Arrays類的靜態方法sort()來排序
        Arrays.sort(array);
        int start=0;
        int end=0;
        for(int i=1;i<array.length;i++){
            if(array[i]== array[start]){
                continue;
            }else{
                if(2*(i-start)>array.length){
                    return array[start];
                }
                start = i;
            }
        }
        return 0;
         
    }
}

另一種思路是這樣的,如果存在一個數字,出現的次數超過一半,那麼它和其他數字“做抵消”,以“一換一”的形式,那麼最後剩下的一定是這個數字(因爲它出現的次數比其餘數字加起來還多),所以可以定義兩個變量,一個變量times記錄次數(但不是總次數),一個記錄temp當前正在判斷的數字,遍歷數組,如果當前數字和正在判斷的數字相等,times加一,否則times減一,如果times爲0,則temp置爲當前遍歷到的數字,times置爲1,直到遍歷結束。

遍歷結束後,並不知道temp是不是所要尋找的數字,但這時只有兩種情況,一種是temp爲所要尋找的數字,一種是不存在索要尋找的數字,這時候可以再遍歷一遍數組,判斷temp是否符合條件。

第一次用這種方法時,我試圖在第一次遍歷時設置一個變量maxTimes,記錄正在判斷的數字出現的最大次數,這樣就不用第二次遍歷了,但是發現失敗了,因爲數組無序,相同數字不挨着,maxTimes常常會被置0,無法達到目的。所以,第二次遍歷應該還是必要的。

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array.length == 0 || array == null){
            return 0;
        }
        if(array.length == 1){
            return array[0];
        }
        int times = 1;
        int temp = array[0];
        for(int i=1;i<array.length;i++){
            if(temp == array[i]){
                times++;
            }
            if(temp != array[i]){
                times--;
                if(times == 0){
                    temp = array[i];
                    times =1;
                }
            }
        }
        if(check(array,temp)){
            return temp;
        }else{
            return 0;
        }
    }
    public boolean check(int[] array,int temp){
        int times=0;
        for(int i=0;i<array.length;i++){
            if(array[i] == temp){
                times++;
            }
        }
        if(times*2>array.length){
            return true;
        }else{
            return false;
        }
    }
}

 

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