169. Majority Element

56 篇文章 0 订阅
40 篇文章 2 订阅


description

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.

解读

找出数组中出现次数超过半数的主元素(肯定存在)

solution

O(n2) 暴力查找

对每一个数都统计出现过的次数,若超过一半则返回该数
这是我第一直觉想到的方法,但是时间开销过大,在OJ上会超时

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

O(nlogn) 分治法

分治解法:
首先将序列平均分成两半,分别找出每一半的主元素。如果两个主元素相等,则直接返回其中一个;否则遍历完整序列,返回两个主元素中出现次数多的那个主元素。
边界条件:序列只有一个元素时,直接返回该元素。

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;

        int lc = 0;
        int rc = 0;
        for (int i = left; i <= right; i++) {
            if (nums[i] == lm) lc++;
            if (nums[i] == rm) rc++;
        }
        return lc > rc? lm: rm;
    }
};

分治法还不算是最优的解法,下面是查阅资料得到的

O(n) Moore’s voting算法1

算法的基本思想

每次都找出一对不同的元素,从数组中删掉,直到数组为空或只有一种元素。 不难证明,如果存在元素e出现频率超过半数,那么数组中最后剩下的就只有e。
当然,最后剩下的元素也可能并没有出现半数以上。比如说数组是[1, 2, 3],最后剩下的3显然只出现了1次,并不到半数。排除这种false positive情况的方法也很简单,只要保存下原始数组,最后扫描一遍验证一下就可以了。

实现描述

因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。
当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。如果下一个数字和我们之前保存的数字不同,则次数减1(删除不同的一对数)。
如果次数为零,我们需要保存下一个数字,并把次数重新设为1。

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

其他方法

sorting O(nlogn)
Randomization O(n)
Bit manipulation位运算 O(n)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值