多數投票算法(Majority Vote Algorithm)
先給一個題目助助興,給一個數組,其中含有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; }