摩爾投票法和大多數

2021-09-26 10:44:19 字數 1507 閱讀 3781

摩爾投票演算法

假設有這樣乙個場景:票選村長,每人可投一票,我們將候選村長從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一下 思路上一題中,超過一半的數隻可能有乙個,所以我們只要投票出乙個數就行...