小小演算法,可笑可笑 摩爾投票法(集萬家之長)

2021-10-21 01:42:40 字數 1867 閱讀 3782

不多說,先上題目。

問題描述:leetcode 229題

給定乙個大小為 n 的整數陣列,找出其中的所有的出現超過 ⌊ n/3 ⌋ 次的元素。

這還不簡單!直接暴力計數,上map,easy搞定。

sorry!還有附加條件,忘記碼上了》_<

設計時間複雜度為 o(n)、空間複雜度為 o(1)的演算法解決此問題。
這下全了》^《如何解呢?空間複雜度o(n)怎麼辦?

別急,先來個中斷,在小本本上記下,咱們先呼叫摩爾投票法。

摩爾投票法

又叫多數投票演算法(boyer–moore majority vote algorithm)

出自這篇**,有興趣的小夥伴可以看看,鍛鍊英語。。

這裡就用漢語描述一下主要內容。

摩爾投票法,演算法解決的問題是如何在任意多的候選人(選票無序),選出獲得票數最多的那個。在無序且侯選人不定的情形,可運用摩爾投票法,投出乙個主席,只要候選人的票數多餘一半,就當選。

演算法的比較次數最多是選票(記為n)的兩倍,可以在 o(n)時間內選出獲票最多的,空間開銷為o(1)。

演算法分為兩個階段:pairing階段和counting階段。

pairing階段(抵消階段):兩個不同選票的人進行對抗,並會同時擊倒對方,當剩下的人都是同一陣營,相同選票時,結束。

counting階段(計數階段):對最後剩下的下進行選票計算統計,判斷選票是否超過總票數的一半,選票是否有效。

這裡有大佬的動畫演示,看完秒懂

這個柱狀圖角度也蠻新穎的

看完一圈回來,相信大家都明白摩爾投票法是什麼了。那最初這個題也會解了吧。

這裡只給出c++的**實現

class

solution

elseif(

!count1)

else

}// 計數階段

count1 = count2 =0;

for(

int i =

0; i < nums.

size()

; i++)}

if(count1 > nums.

size()

/3) ans.

push_back

(cand1);if

(count2 > nums.

size()

/3) ans.

push_back

(cand2)

;return ans;}}

;

1.摩爾投票法的第一步pairing是用來在o(n)時間和o(1)空間內,選出眾數來。

2.因為是選出眾數,例如在[1,2,3]中,1或2或3都是眾數,因此,還需要第二不counting重新再遍歷一邊,統計選出的的票數是否多餘1/2。

3.由此可以推廣,如果選出兩名主席,則pairing步驟需要找出兩個眾數,counting需要檢查,每個選出來個的主席是否票數都多餘1/3。

如果要選出m名主席,要選出m個眾的數,檢查是否都多餘1/(m+1)。

4.還有什麼???沒了。。。哦對!還有其他解法。

比如:雜湊表方法和排序法找中位數(這個只使用選出乙個主席的情況哦)

雜湊map:

class

solution

};

排序:

int

majorityelement

(vector<

int>

& nums)

參考文章

1.多數投票演算法(boyer-moore algorithm)詳解

3.boyer–moore majority vote algorithm

演算法 摩爾投票法

遇到乙個演算法的題目,找到陣列 現次數最多的數,並且判斷是否超過了陣列一半。我最開始想了3種方案,第一種 用hashset把資料傳入,並且記錄false的次數,最後和陣列長度比較。第二種 用兩個指標迴圈比較資料有沒有重複的,有的話count 1,最和陣列長度比較。第三種 第三種就是本文要介紹的一種演...

摩爾投票法

刷leetcode看到的一種解法。想法其實很簡單。上網上看了下這種解法叫摩爾投票法。其實就是找array裡的眾數,原理也很簡單,例如你要找2 n多的數你找眾數,那他個數肯定不小於2 n,然後你加加減減 最後留下那個肯定是眾數。3 n 什麼的情況也一樣,畫一畫就明白了。然後這是別人的解析 摩爾投票法 ...

摩爾投票法

該演算法用於解決尋找乙個含有 n n 個元素的數列 role presentation 中出現超過1k 1 k 即大於nk n k次 的元素 假設滿足要求的元素存在 可知,滿足要求的元素最多有 k 1 k 1 個。使用暴力解法並不難,但是摩爾投票法給出了乙個o n o n 時間複雜度的解法。當k 2...