摩爾投票演算法
假設有這樣乙個場景:票選村長,每人可投一票,我們將候選村長從1開始編號,村民們在票上寫上候選村長的編號即可完成投票。那麼最後統計的票可形成乙個整型陣列。那麼誰是村長呢?票數過半的那個人。
摩爾投票演算法可以快速的計算出乙個陣列**現次數過半的數即大多數(majority),演算法核心思想是同加,異減。我們舉個例子。
假設陣列是:[1,2,1,1,2,1]。演算法步驟如下:
1。當前大多數是1,得分置1
2。與當前大多數不同,得分 - 1,得分為0,當前大多數 = 1
1。與當前大多數不同,得分為0,所以設定當前大多數 1 -> 1,得分置1
1。與當前大多數相同,得分 + 1,得分為2,當前大多數 = 1
2。與當前大多數不同,得分 - 1 ,得分為1,當前大多數 = 1
1。與當前大多數相同,得分 + 1,得分為2,當前大多數 = 1
這意味著1是這個陣列**現次數過半的數。
可以感受得到,演算法會儲存乙個當前大多數,和得分,當遇到乙個數不是當前大多數時,得分會減一,當減到0時,大多數會發生改變,並且重置得分為1。
這裡需要區分的是,摩爾演算法不能用來得到眾數(mode),例如陣列:[1,1,1,2,2,3,3,4,4],摩爾演算法得出最後的結果應該是4,但4並不是眾數,可是顯然4也不是大多數,那是因為,大多數是指出現次數過半的數,而這個陣列中沒有這樣的數,所以摩爾演算法是是失效的,對於這種情況採取需要重新投票。
出現次數超過一半的數
leetcode原題:169. majority element
這裡要求出現次數大於一半,所以直接套用摩爾投票演算法即可得到答案。
————————————————
class solution(object):
def majorityelement(self, nums):
""":type nums: list[int]
:rtype: int
"""a, ca = none, 0
for n in nums:
if a == n : ca += 1
elif ca == 0: a, ca = n, 1
else : ca -= 1
return a
————————————————
出現次數超過陣列1/3長
leetcode原題:229. majority element ii
還能用摩爾投票法嗎?答案當然是要,但是需要變通一下。
需要注意的是出現次數超過1/3陣列長的數,也許會有多個,例子如下:
[1,1,1,2,2,2,3,3],陣列1/3長=2(向下取整),所以1和2都是符合條件的。
但最多只能是2個
回到題目
如果我們在使用摩爾演算法時,同時記錄兩個大多數,會怎麼樣呢?直覺告訴我,這會得到乙個大多數,和乙個出現次數僅次於大多數的數,但是這兩個數不一定會比數組長的1/3大
所以我們得到它們後,還需要檢查它們出現的次數是否符合條件。
ac**:
摩爾投票法
刷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...
摩爾投票法
複雜度時間 o n 空間 o 1 因為多於三分之一的數可能有2兩個,所以需要用兩個值和兩個計數器過一遍,但是最後得出來不一定是兩個數都是多於三分之一,有可能 只有乙個是多於三分之一,但不知道是哪乙個,所以要重新過一遍check一下 思路上一題中,超過一半的數隻可能有乙個,所以我們只要投票出乙個數就行...