1. 程式人生 > >[LeetCode] Majority Element II 求眾數之二

[LeetCode] Majority Element II 求眾數之二

Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time and in O(1) space.

Hint:

  1. How many majority elements could it possibly have?
  2. Do you have a better hint? Suggest it!

這道題讓我們求出現次數大於n/3的眾數,而且限定了時間和空間複雜度,那麼就不能排序,也不能使用雜湊表,這麼苛刻的限制條件只有一種方法能解了,那就是摩爾投票法 Moore Voting,這種方法在之前那道題

Majority Element 求眾數中也使用了。題目中給了一條很重要的提示,讓我們先考慮可能會有多少個眾數,經過舉了很多例子分析得出,任意一個數組出現次數大於n/3的眾數最多有兩個,具體的證明我就不會了,我也不是數學專業的。那麼有了這個資訊,我們使用投票法的核心是找出兩個候選眾數進行投票,需要兩遍遍歷,第一遍歷找出兩個候選眾數,第二遍遍歷重新投票驗證這兩個候選眾數是否為眾數即可,選候選眾數方法和前面那篇Majority Element 求眾數一樣,由於之前那題題目中限定了一定會有眾數存在,故而省略了驗證候選眾數的步驟,這道題卻沒有這種限定,即滿足要求的眾數可能不存在,所以要有驗證。程式碼如下:

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        vector<int> res;
        int m = 0, n = 0, cm = 0, cn = 0;
        for (auto &a : nums) {
            if (a == m) ++cm;
            else if (a ==n) ++cn;
            else if (cm == 0
) m = a, cm = 1; else if (cn == 0) n = a, cn = 1; else --cm, --cn; } cm = cn = 0; for (auto &a : nums) { if (a == m) ++cm; else if (a == n) ++cn; } if (cm > nums.size() / 3) res.push_back(m); if (cn > nums.size() / 3) res.push_back(n); return res; } };

類似題目:

參考資料: