不多說,先上題目。
問題描述: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...