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.(给定一个大小为n的数组,找出majority element,majority element是指在数组中出现超过n/2次的元素)
You may assume that the array is non-empty and the majority element always exist in the array.(假设数组是非空的,并且majority element总是存在的)

1.个人分析
思路:
(1)从头到尾遍历数组,统计每个不同元素在数组中的个数,找出个数大于n/2的元素。
(2)先将数组进行排序,显然排序后的数组中相同元素都相邻排列,然后统计不同元素的个数,最后找出个数大于n/2的元素。

2.个人解法

int majorityElement(vector<int>& nums) 
{
    int counterLen = nums.size();
    int *counter = new int[counterLen];

    for(int i=0; i<counterLen; ++i)
        counter[i] = 0;

    int key;
    for (int i=0; i<counterLen; ++i)        
    {
        key = nums[i] % counterLen;
        if(key < 0)
            key += counterLen;
        ++counter[key] ;        
        if(counter[key] > (counterLen/2))
            return nums[i];
    }

    return -1;
}

结果显示能够通过所有测试用例,时间和空间复杂度都为O(n),只不过这里要注意当进行哈希散列过程中key为负数的情况,教材给出的处理方法是key=key + tableSize。

3.参考解法
(1)

int majorityElement(vector<int>& nums) {
    int winner = 0;
    for (int i=0; i<32; i++) {
        int ones = 0;
        for (int n : nums)
            ones += (n >> i) & 1;
        winner += (ones > nums.size() / 2) << i;
    }
    return winner;
}

这种解法涉及到位运算

(2)

 int majorityElement(int[] num) {
       int major=num[0], count = 1;
       for(int i=1; i<num.length;i++){
           if(count==0){
               count++;
               major=num[i];
           }else if(major==num[i]){
               count++;
           }else count--;

       }
       return major;
 }

上面解法是Java实现的,可能是所有方法里最快的,记得该方法是来源自一篇学术论文中的成果,但是自己还不理解其实现的原理。

4.总结
看了这道题其他人给出的各种解法后,发现算法的水非常深,只有你想不到,没有实现不了更快更简洁的方法。

PS:

  • 题目的中文翻译是本人所作,如有偏差敬请指正。
  • 其中的“个人分析”和“个人解法”均是本人最初的想法和做法,不一定是对的,只是作为一个对照和记录。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值