1. 程式人生 > 其它 >leetcode229229. 求眾數 II(hash 摩爾投票)

leetcode229229. 求眾數 II(hash 摩爾投票)

連結:https://leetcode-cn.com/problems/majority-element-ii/

題目

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

用例

示例1:

輸入:[3,2,3]
輸出:[3]
示例 2:

輸入:nums = [1]
輸出:[1]
示例 3:

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

提示:

1 <= nums.length <= 5 * 104
-109 <= nums[i] <= 109

進階:嘗試設計時間複雜度為 O(n)、空間複雜度為 O(1)的演算法解決此問題。

思路

方法一
樸素hash表篩選
用雜湊表記錄每一個數字出現的頻率

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        int n=nums.size()/3;
        unordered_map<int,int>mp;
        vector<int>ans;
        for(auto a:nums){
            mp[a]++;       
        }
        for(auto b:mp){
            if(b.second>n)
                ans.push_back(b.first);
        }
        return ans;
    }
};

方法二
摩爾投票法
關聯leetcode169.多數元素(連結:https://leetcode-cn.com/problems/majority-element/)
對於僅存在一個出現次數 大於 ⌊ n/2 ⌋ 的元素
可以對設定摩爾投票
設定e1記錄元素 設定c1記錄投票數量
遍歷陣列 當投票數c1>0且當前nums[i]與記錄元素e1相等時 c1++
當c1==0時,e1變化為nums[i],且c1++
其實就是一個消消樂思想 每次把兩個不同的數字刪去

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int n=nums.size();
        int e1=0,v1=0;
        for(auto num :nums){
            if(v1==0){
                e1=num;
                v1++;
            }else if(e1==num){
                v1++;
            }else{
                v1--;
            }
        }
        return e1;
    }
};

本題求眾數 也可以用這個思想
出現次數超過 ⌊ n/3 ⌋ 次的元素,在陣列中至多隻能存在2個
我們可以每次消除三個不同的數,來獲取候選答案(候選答案為出現頻率前2的元素,但其中一個不一定滿足條件)
最後對候選答案進行驗證 判定是否大於 ⌊ n/3 ⌋ 次

class Solution {
public:
    vector<int> majorityElement(vector<int>& nums) {
        int n=nums.size()/3;
        int e1=0,e2=0,c1=0,c2=0;
        for(auto a:nums){
            if(a==e1&&c1>0){
                c1++;
            }else if(a==e2&&c2>0){
                c2++;
            }else if(c1==0){
                e1=a;
                ++c1;
            }else if(c2==0){
                e2=a;
                ++c2;
            }else{
                c1--;
                c2--;
            }
        }
        c1=0;
        c2=0;
        for(auto a:nums){
            if(a==e1)
                c1++;
            if(a==e2)
                c2++;
        }
        vector<int>ans;
        if(c1>n)
            ans.push_back(e1);
        if(c2>n)
        {
            if(e1!=e2)
                ans.push_back(e2);
        }
        return ans;
    }
};