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

    分析:题意为在大小为n的数组中找到多数元素,多数元素出现次数大于⌊ n/2 ⌋

    思路:没找到两个不同的元素就成对删除,最后剩下的一定是所求的元素(因为假设了数组非空,而且多数元素总是存在的)

    实现方式:顺序遍历数组元素,前后不同则计数减一,相同则加一,在此过程中将所求元素存放到tem中

    代码如下:

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

     其他解法:

    直接使用sort()函数对数组进行排序,则所求元素必定在排序后的数组正中间

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

     亦可参照:

    Moore Voting Algorithm

    A brilliant and easy-to-implement algorithm! It also runs very fast, about 20ms.

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            int major, counts = 0, n = nums.size();
            for (int i = 0; i < n; i++) {
                if (!counts) {
                    major = nums[i];
                    counts = 1;
                }
                else counts += (nums[i] == major) ? 1 : -1;
            }
            return major;
        }
    };
    

    Bit Manipulation

    Another nice idea! The key lies in how to count the number of 1's on a specific bit. Specifically, you need a mask with a 1 on the i-the bit and 0 otherwise to get the i-th bit of each element in nums. The code is as follows.

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            int major = 0, n = nums.size();
            for (int i = 0, mask = 1; i < 32; i++, mask <<= 1) {
                int bitCounts = 0;
                for (int j = 0; j < n; j++) {
                    if (nums[j] & mask) bitCounts++;
                    if (bitCounts > n / 2) {
                        major |= mask;
                        break;
                    }
                }
            } 
            return major;
        } 
    };

    Divide and Conquer

    This idea is very algorithmic. However, the implementation of it requires some careful thought about the base cases of the recursion. The base case is that when the array has only one element, then it is the majority one. Moreover, this solution is relatively slow in practice.

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            return majority(nums, 0, nums.size() - 1);
        }
    private:
        int majority(vector<int>& nums, int left, int right) {
            if (left == right) return nums[left];
            int mid = left + ((right - left) >> 1);
            int lm = majority(nums, left, mid);
            int rm = majority(nums, mid + 1, right);
            if (lm == rm) return lm;
            return counts(nums, lm) > counts(nums, rm) ? lm : rm;
        }
        int counts(vector<int>& nums, int elem) {
            int cnt = 0;
            for (int i = 0; i < int(nums.size()); i++)
                if (nums[i] == elem) cnt++;
            return cnt;
        }
    };

    Randomization

    This is a really nice idea and works pretty well (16ms running time on the OJ, almost fastest among the C++ solutions). The proof is already given in the suggested solutions.

    The code is as follows, randomly pick an element and see if it is the majority one.

    class Solution {
    public:
        int majorityElement(vector<int>& nums) {
            int n = nums.size();
            srand(unsigned(time(NULL)));
            while (true) {
                int idx = rand() % n;
                int candidate = nums[idx];
                int counts = 0; 
                for (int i = 0; i < n; i++)
                    if (nums[i] == candidate)
                        counts++; 
                if (counts > n / 2) return candidate;
            }
        }
    };

    Hash Table

    The hash-table solution is very straightforward. We maintain a mapping from each element to its number of appearances. While constructing the mapping, we update the majority element based on the max number of appearances we have seen. Notice that we do not need to construct the full mapping when we see that an element has appeared more than n / 2 times.

    The code is as follows, which should be self-explanatory.

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

     

     

  • 相关阅读:
    免费馅饼(HDU 1176 DP)
    搬寝室(HDU 1421 DP)
    FatMouse's Speed(HDU LIS)
    Bone Collector II(HDU 2639 DP)
    Palindrome(POJ 1159 DP)
    Proud Merchants(POJ 3466 01背包+排序)
    树的最大独立集
    Roads in the North(POJ 2631 DFS)
    Starship Troopers(HDU 1011 树形DP)
    Strategic game(POJ 1463 树形DP)
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/4687711.html
Copyright © 2020-2023  润新知