169. Majority Element

15 篇文章 0 订阅
11 篇文章 0 订阅

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.

思路:Leetcode里面给的标签是ArrayDivide and Conquer, 和Bit Manipulation。所以我们先考虑Hash TableBit manipulationDivide and Conquer这三种方法。

1、Hash Table: 用unordered_map 记录每个nums[i]出现的次数,只要某一个nums[i]出现的次数大于 ⌊ n/2 ⌋次,就返回。代码如下:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        unordered_map<int, int> map;
        int major;

        for (int i = 0; i < nums.size(); ++i){
            if(++map[nums[i]] > nums.size() / 2)
                major = nums[i];
        }
        return major;
    }
};

2.Bit Manipulation
思路是:既然某一个数nums[i]出现的次数大于 ⌊ n/2 ⌋次,那么它所对应的二进制数在每一个bit(无论nums[i]对应的值是0或者1)上出现的次数也一定大于 ⌊ n/2 ⌋次。例如,假设某一个bit位上nums[i]对应的值是0,那么nums这个数组的每个数,依次跟这一位是1而其他位上全部是0的mask进行运算,一共出现的count数一定不会超过⌊ n/2 ⌋;假设某一个bit位上nums[i]对应的值是1,那么nums这个数组的每个数,依次跟这一位是1而其他位上全部是0的mask进行运算,一共出现的count数一定超过⌊ n/2 ⌋。因此,只要count数超过⌊ n/2 ⌋,就把 major(初值为0)跟mask做
操作,这样就可以还原major在这个二进制位上的值。最终,32位依次操作完,我们就得到了major。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
    int major = 0;

    for(int i = 0, mask = 1; i < 32; i++, mask <<= 1){
            int count = 0;
        for(int j = 0; j < nums.size(); ++j){
            if(nums[j] & mask)
                count++;
            if(count > nums.size() / 2){
                major = major | mask;
                break;
            }
        }
    }
    return major;
    }
};

3.Divide and Conquer
代码如下:

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

        return count(nums.begin(), nums.end(), lm) > count(nums.begin(), nums.end(), rm) ? lm : rm;
    }
};

4.Sorting 先按照大小排序,返回nums[nums.size() / 2]即可。

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

也可以用c++ STL的 nth_element, 直接排序前nums.size() / 2个数即可

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

5.Moore Voting Algorithm
简单来说,基本思路是: If we cancel out each occurrence of an element e with all the other elements that are different than from e, then e will exist till the end, if it is a major element.
代码如下:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int major = 0, counts = 0, n = nums.size();
        for(int i = 0; i < n; ++i){
            if(counts == 0){
                major = nums[i];
                counts = 1;
            }
            else
                counts+= (nums[i] == major)? +1 : -1;
        }
        return major;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值