摩爾投票法

2021-08-07 16:09:51 字數 1934 閱讀 5957

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

然後這是別人的解析-

摩爾投票法

提問: 給定乙個int型陣列,找出該陣列中出現次數最多的int值。

解決方案: 遍歷該陣列,統計每個int值出現次數,再遍歷該集合,取出出現次數最大的int值。

這算是乙個比較經典的解決辦法,其中可能會用到map來做統計。如果不使用map,則時間複雜度會超過線性複雜度。除此之外,也沒有什麼特別好的辦法。

今天在leetcode上遇到這樣一道題目,

提問: 給定乙個int型陣列,找出該陣列中出現次數大於陣列長度一半的int值。

解決方案: 遍歷該陣列,統計每個int值出現次數,再遍歷該集合,找出出現次數大於陣列長度一半的int值。

同樣的,該解決辦法也要求使用map,否則無法達到線性的時間複雜度。

那麼對於這個問題,有沒有什麼不使用map的線性演算法呢?

答案就是今天我們要提到的摩爾投票法。利用該演算法來解決這個問題,我們可以達到線性的時間複雜度以及常量級的空間複雜度。

首先我們注意到這樣乙個現象: 在任何陣列中,出現次數大於該陣列長度一半的值只能有乙個

通過數學知識,我們可以證明它的正確性,但是這並不在我們這篇部落格裡涉及。

摩爾投票法的基本思想很簡單,在每一輪投票過程中,從陣列中找出一對不同的元素,將其從陣列中刪除。這樣不斷的刪除直到無法再進行投票,如果陣列為空,則沒有任何元素出現的次數超過該陣列長度的一半。如果只存在一種元素,那麼這個元素則可能為目標元素。

那麼有沒有可能出現最後有兩種或兩種以上元素呢?根據定義,這是不可能的,因為如果出現這種情況,則代表我們可以繼續一輪投票。因此,最終只能是剩下零個或乙個元素。

在演算法執行過程中,我們使用常量空間實時記錄乙個候選元素c以及其出現次數f(c),c即為當前階段出現次數超過半數的元素。根據這樣的定義,我們也可以將摩爾投票法看作是一種動態規劃演算法

程式開始之前,元素c為空,f(c)=0。遍歷陣列a:

* 如果f(c)為0,表示截至到當前子陣列,並沒有候選元素。也就是說之前的遍歷過程中並沒有找到超過半數的元素。那麼,如果超過半數的元素c存在,那麼c在剩下的子陣列中,出現次數也一定超過半數。因此我們可以將原始問題轉化為它的子問題。此時c賦值為當前元素, 同時f(c)=1。

* 如果當前元素a[i] == c, 那麼f(c) += 1。(沒有找到不同元素,只需要把相同元素累計起來)

* 如果當前元素a[i] != c,那麼f(c) -= 1 (相當於刪除1個c),不對a[i]做任何處理(相當於刪除a[i])

如果遍歷結束之後,f(c)不為0,則找到可能元素。

再次遍歷一遍陣列,記錄c真正出現的次數,從而驗證c是否真的出現了超過半數。上述演算法的時間複雜度為o(n),而由於並不需要真的刪除陣列元素,我們也並不需要額外的空間來儲存原始陣列,空間複雜度為o(1)。

我的**實現:

vector

res;

int m = 0, n = 0, cm = 0, cn = 0

;

for (auto &a : nums)

cm = cn = 0

;

for (auto &a : nums)

if (cm > nums.size() / 3

) res.push_back(m);

if (cn > nums.size() / 3

) res.push_back(n);

return

res;

摩爾投票法

該演算法用於解決尋找乙個含有 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一下 思路上一題中,超過一半的數隻可能有乙個,所以我們只要投票出乙個數就行...

摩爾投票法

提問 給定乙個int型陣列,找出該陣列 現次數最多的int值。解決方案 遍歷該陣列,統計每個int值出現次數,再遍歷該集合,取出出現次數最大的int值。這算是乙個比較經典的解決辦法,其中可能會用到map來做統計。如果不使用map,則時間複雜度會超過線性複雜度。除此之外,也沒有什麼特別好的辦法。今天在...