在面試題中經常會出現這樣一個題目,給一個數組,其中含有N個非負元素,讓你求出數組中出現次數超過一半的數字。
看到這個問題我們首先想到的可能是暴力的解法,那就是將數組排個序,輸出中間的元素就行了,因為如果出現次數超過一半的話排完序后中間的那個元素肯定是我們需要求的值。
這樣做的話排序的時間復雜度一般來說是O(NlogN),那么有沒有時間復雜度為n的算法呢?
答案當然是有的,有這樣的一個算法,Majority Vote Algorithm,他是這樣的做的:設置一個計數器count和保存最多元素的變量majority,
- 如果count==0,則將now的值設置為數組的當前元素,將majority賦值為1;
- 反之,如果majority和現在數組元素值相同,則count++,反之count--;
- 重復上述兩步,直到掃描完數組。
- count賦值為0,再次從頭掃描數組,如果素組元素值與majority的值相同則count++,直到掃描完數組為止。
- 如果此時count的值大於等於n/2,則返回majority的值,反之則返回-1。
代碼的簡單實現如下:
public int Find_Majority(int [] array) { int major=0, count = 0; int i=0; while(i<array.length){ if(i==0){ major=array[0]; count=1; }else if(major==array[i]){ //如果數組掃描到的數和當前majority數相等。 count++; }else if(major!=array[i]&&count!=0){//如果數組掃描到的數和當前majority數不相等,且當前majority數的票數至少有一票。 count--; }else{ major=array[i]; } i++; } int tmp_count=0; for(int j=0;j<array.length;j++){ if(array[j]==major) tmp_count++; } if(tmp_count>=(array.length+1)/2) //檢驗majority數的票數是否超過了總票數的一半 return major; else return -1; }