摩爾投票法

2021-10-07 07:04:12 字數 2454 閱讀 9510

摩爾投票法可以用來尋找陣列中的多數元素。

經典的摩爾投票法用來尋找陣列**現次數超過一半的元素,注意一定是出現次數超過一半,剛好等於一半是不能用這種演算法的。如leetcode 169:

給定乙個大小為 n 的陣列,找到其中的多數元素。多數元素是指在陣列**現次數大於 ⌊ n/2 ⌋ 的元素。

你可以假設陣列是非空的,並且給定的陣列總是存在多數元素。

示例 1:

輸入: [3,2,3]

輸出: 3

示例 2:

輸入: [2,2,1,1,1,2,2]

輸出: 2

乙個陣列**現次數大於n/2的元素最多只有1個。考慮這樣一種做法:每次選原陣列中的兩個不同的數抵消,這樣,最後陣列中只可能剩下1種數,或0個數,如果剩下1種數,那麼再檢驗一下這個數就是要找的多數元素。如果用乙個陣列arr來儲存當前未能抵消的元素,那麼這個過程如下:

以 nums = 為例,開始時,arr = {}。

掃瞄到 2 :因為arr為空,直接放到arr中,原陣列不變。 arr = , nums = ;

掃瞄到2 :與arr中的元素相同,因此也放到arr中,原陣列不變。arr = , nums =  ;

掃瞄到1:與arr中的元素不同,可以抵消1個,原陣列也對應抵消1個2和1個1。arr = , nums = ;

掃瞄到1:與arr中的元素不同,可以抵消1個,原陣列也對應抵消1個2和1個1。arr = {}, nums = ;

掃瞄到1:因為arr為空,直接放到arr中,原陣列不變。arr = , nums = 。

掃瞄到2:與arr中的元素不同,可以抵消1個,原陣列對應抵消1個1和1個2。arr = {}, nums = 。

掃瞄到2:arr為空,直接放到arr中,arr = , nums = 。

所以,最後剩下的一種元素是2。最後統計2在原陣列中的出現次數,確實大於n/2。那麼就找到了多數元素。

觀察這一過程,arr中存在的數最多只有1種,所以可以用兩個變數來代替arr,majority: arr中的數,count: arr的長度,就可以寫出摩爾投票法的**:

掃瞄到數字i時,分三種情況:

(1) arr非空,並且i與arr中的數相同,即 i == majority, 那麼 count++,對應arr長度++。

(2) arr是空集,那麼 majority = i, count++。

(3) i 是與 arr中的數不同的數,那麼相互抵消, count--, 對應 arr長度--。

class solution 

else count--;

}return majority;

}};

這裡最後沒有檢驗majority是否真的出現了超過n/2次,是因為題目中保證了多數元素一定存在,所以剩下的一定是多數元素。

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

說明: 要求演算法的時間複雜度為 o(n),空間複雜度為 o(1)。

示例 1:

輸入: [3,2,3]

輸出: [3]

示例 2:

輸入: [1,1,1,3,3,2,2,2]

輸出: [1,2]

超過n/3次的元素最多只有2個,所以可以找到出現次數前二大的元素,再判斷它們是否符合條件。

用摩爾投票法找出現次數前二大的元素,就需要兩組 majority和count變數(隱含的是2個arr),做法如下:

掃瞄到數字i,分5種情況(互斥):

(1) arr1非空,且i與arr1中的數字majority1相同,那麼count1++, 掃瞄下乙個數。

(2) arr2非空,且i與arr2中的數字majority2相同,那麼count2++, 掃瞄下乙個數。

(3) arr1空,那麼把 i 放到 arr1中, 即 majority1 = i, count1++,掃瞄下乙個數。

(4) arr2空,那麼把 i 放到 arr2中,即 majority2 = i, count++, 掃瞄下乙個數。

(5) arr1和arr2都非空,且i與arr1和arr2中的數都不相同,那麼將 arr1和arr2的長度都--,作為抵消。

最後檢查 majority1和majority2是否滿足 > n/3次的條件。

class solution 

else if(count2 == 0)

else

}count1 = 0, count2 = 0;

for(int i : nums)

vectorans;

if(count1 > nums.size() / 3) ans.push_back(majority1);

if(count2 > nums.size() / 3) ans.push_back(majority2);

return ans;

}};

摩爾投票法

刷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一下 思路上一題中,超過一半的數隻可能有乙個,所以我們只要投票出乙個數就行...