zoukankan      html  css  js  c++  java
  • 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];
        }
    };

     

     

  • 相关阅读:
    ArcEngine:GP使用!没道理的错误!
    XMLHttpRequest的亲密接触(1)——简单讲解
    XMLHttpRequest的亲密接触(2.2)——表单提交
    初入Ajax,需要明确的Web工作原理
    文章收藏明细
    【备忘】Oracle10g 创建、删除表空间、创建、授权用户
    proxool的使用总结
    Java操作压缩与解压缩
    解决jquery ui dialog中调用datepicker时日期选择控件被遮挡的问题
    如何读取jar包中的xml等资源文件
  • 原文地址:https://www.cnblogs.com/carsonzhu/p/4687711.html
Copyright © 2011-2022 走看看