leetcode: 169. Majority Element

169. Majority Element

题目地址
这道题目实际上是一道求众数的问题,题目的关键more than ⌊ n/2 ⌋
主要有三种思路

  • 方法一:排序后取nums[n/2],时间复杂度O(nlogn)(这里使用了快排)
    由于所求数的个数一定大于[n/2],所以排序后[n/2] 的位置一定是众数
int majorityElement(vector<int>& nums) {
        int count=1;
        int n=nums.size();
        sort(nums.begin(),nums.end());
        return nums[n/2];
    }
  • 方法二:位操作 时间复杂度 O(n)
    这是之后看到大神做的一种方法(https://www.jianshu.com/p/dfd676b71ef0)在这里贴出思路和代码
    设int为32位整数。我们对这些数以二进制的形式,逐位观察,尝试构造出主要元素来。对32位中的每一位,如果1占多数,则主要元素的对应位为1,否则为0
int majorityElement(int[] nums) {
   int res=0,major=nums.length/2;
   for (int i=31;i>=0;i--){
       int pos=0;
       for(int n:nums)
          pos+=(n>>i)&1;
       pos=pos>major? 1:0;
       res|=pos<<i;
    }
    return res;
}
  • 方法三:摩尔多数票算法
    时间复杂度O(n)
    这个算法算是本题最大的收获了~很有趣的一个算法 维基百科:Moore majority vote algorithm
    基本思想就是找到两个不相同的元素然后删除,直到最后剩下的元素都相同,在数组中我们可以通过设置计数变量来实现。摩尔算法的缺点是找到的元素不一定是多数元素 需要后续验证
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;
    }

之后又趁热打铁做了 229. Majority Element II 题目链接
条件改为 find all elements that appear more than ⌊ n/3 ⌋ times
将摩尔多数票算法进行拓展,就可以解决该问题。根据题意,候选元素的个数只可能是 0个,1个,2个 我们可以设置两组计算变量和候选元素变量 count1,major1count2,major2。注意:最后需要对候选元素进行验证

vector<int> majorityElement(vector<int>& nums) {
        vector<int> res;
        int n=nums.size();
        int count1=0,count2=0;
        int k1=0,k2=0;
        if(n==0)
        {
            return res;
        }
        if(n==1)
        {
            return nums;
        }
        int major1=nums[0],major2=nums[1];
        for(int i=0;i<n;i++)
        {
            if(major1==nums[i])
            {
                count1++;
            }
            else if(major2==nums[i])
            {
                count2++;
            }
            else if(count1==0)
            {
                major1=nums[i];
                count1=1;
            }
            else if(count2==0)
            {
                major2=nums[i];
                count2=1;
            }
            else
            {
                count1--;
                count2--;
            }
        }
        for(int j=0;j<n;j++)
        {
            if(major1==nums[j])
            {
                k1++;
            }
            if(major2==nums[j])
            {
                k2++;
            }    
        }
        if(k1>n/3)
            res.push_back(major1);
        if(k2>n/3&&major1!=major2)
            res.push_back(major2);
        return res;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值