Leetcode之Majority Element I II

169. Majority Element

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.

Method 1: Boyer-Moore Voting method The
Boyer-Moore Voting method first assumes the first number as the mode, then sets the counter to 1, and compares the next number and this number to see if they are equal. If they are equal, the counter is incremented by one. Otherwise, subtract one. Then look at the value of the counter at this time, if it is zero, set the current value as the candidate mode. And so on until the entire array is traversed, and the current candidate mode is the mode of the array. Since there must be a mode in the question, the step of verifying the mode of the candidates is omitted.
The time complexity of this method is O(n) and the space complexity is O(1).

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int count = 1;
        int majority = nums[0];
        for(int i = 1;i < nums.size();i++){
            if(nums[i] == majority)
                count++;
            else
                count--;
            if(count == 0){
                majority = nums[i];
                count = 1;
            }
        }
    }
};

Method 2: Hash table
Using a hash table, the key is used to store the elements of the array, and the value corresponding to the key is used to store the number of occurrences of the element. Traverse the entire array to find if it appears in the hash table, if it does, add 1 to the occurrence count, if not, insert it into the hash table and set its occurrence count to 1. Each time an element is traversed, it is judged whether the number of occurrences of it exceeds half of the length of the array, and if so, the element is returned.
The time complexity is O(n) and the space complexity is O(n).

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        if(nums.size()==1)
            return nums[0];
        unordered_map<int,int> mp;
        for(int i=0;i<nums.size();i++){
            if(mp.count(nums[i])){
                mp[nums[i]]++;
                if(mp[nums[i]]>nums.size()/2)
                    return nums[i];
            }
            else
                mp[nums[i]]=1;
        }
};

Method 3: Sorting
To sort the array, the element with more than half of the occurrences must be the middle element in the array, and this element can be returned.
The time complexity is O(nlogn) and the space complexity is O(1).

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        return nums[nums.size()/2];
    }
};

Method 4: Bit manipulation Bit Manipulation
establishes the median bit by bit, from 0 to 31 bits, counts the number of 0 and 1 on the bit in the array each time, if there are more than 1, then we put the bit in the result res becomes 1, and the final accumulated res is the median

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int res = 0;
        for (int i = 0; i < 32; ++i) {
            int ones = 0, zeros = 0;
            for (int num : nums) {
                if ((num & (1 << i)) != 0) ++ones;
                else ++zeros;
            }
            if (ones > zeros) res |= (1 << i);
        }
        return res;
    }
};

229. 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.

This question asks us to find the mode with the number of occurrences greater than n/3, and the time and space complexity are limited, so we can't sort, and we can't use a hash table. There is only one way to solve such a harsh restriction. That is the Moore voting method, which is also used in the previous question, Majority Element. There is an important conclusion that there are at most two modes in which the number of occurrences of any array is greater than n/3. The core of our voting method is to find out the two candidate modes for voting, which requires two traversals, the first traversal to find the two candidate modes, and the second traversal to re-vote to verify whether the two candidate modes are modes. That is, the method of selecting the mode of the candidate is the same as that of the previous Majority Element. Since there must be a mode in the previous question, the step of verifying the mode of the candidate is omitted, but this question does not have such a mode. Restriction, that is, the mode that meets the requirements may not exist, so there must be verification.

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;
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325600105&siteId=291194637