※ Leetcode - Array - 169. Majority Element(快速找出数组中出现过一半以上次数的数,3种写法)

1.7.1 Problem Description

Given an array of size n, find the majority element. The majority element is the element that appears more thann/2 times.

You may assume that the array is non-empty and the majority element always exist in the array.

求给定数组中出现n/2次以上(不含n/2)的数字。

2. My solution1:Hash countO[n]

计算每个数出现的次数直接输出出现次数最多的数。

   int majorityElement(vector<int>& nums)
    {
       map<int,int>hh;
       int len=nums.size();
       int ansindex=0;
       for(int i=0;i<len;i++)
       {
          hh[nums[i]]++;
          if(hh[nums[i]]>hh[nums[ansindex]])
            ansindex=i;
       }
       return nums[ansindex];
    }

3.My solution2 排序输出中间数(O[nlogn])

偷懒的做法,因为已经表示出现次数多于一半,直接排序后输出中间的那个数(偶数奇数都是n/2位置)即可。

    int majorityElement(vector<int>& nums)
    {
        int len=nums.size();
        sort(nums.begin(),nums.end());
        return nums[len/2];
    }

 

4. Brilliant Algorithm(O[n])

这种做法只有majority number存在的时候才可以使用,Brilliant Algorithm

每找出两个不同的element,则成对删除。最终剩下的一定就是所求的。

算法思路来自陆草纯的博客,这里把他在leetcode上的证明简单阐述一下。

 

扩展到[n/k]的情况:将每k个不同的element进行成组删除,剩下的就是所求的数字。

 

证明:

假设我们将这n个数每k个数编组(保证每个组内的k个数互不相同),这样可以有n/k个组,每个组只有一个Majority Number

 

由于这个数出现了超过n/k次,假设是n/k+1次。

 

那么当我们计算到第n/k-1个组时,由于“每个组只有一个Majority Number”,这里我们已经计算了(n/k-1)*k个数,而Majority Number出现了n/k-1次。

 

那么剩下的k个数中,必然存在至少两个Majority Number

 

在下文中的code中,我们最终保留的(Answer)实际是在最后一个组中重复出现的数字。自然也就是Majority Number

 

class Solution {
    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;
    }
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值