C++ LeetCode 169 多数元素

给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [3,2,3]
输出: 3

示例 2:

输入: [2,2,1,1,1,2,2]
输出: 2

map

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        map<int,int> mp;
        for(int i=0;i<nums.size();i++)
        {
            mp[nums[i]]+=1;
            if(mp[nums[i]]>nums.size()/2)
                return nums[i];
        }
        return -1;
    }
};

排序法

因为大于一半的数,所有数组中心位置必然是众数。

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

随机法

因为众数占一半,所以随机找一个数大概率是要找的众数,赌就完事了

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        srand(time(NULL));
       while(1)
       {
           int n=nums.size();
           int ans=0;
           int re=nums[rand()%n];
           for(int nu:nums)
                if(nu==re)
                    ans++;
            if(ans>n/2)
                return re;

       }
    }
};

分治法

每一次把区间分为两部分,分别寻找两个区间(0,mid),(mid+1,n-1)的众数a和b,要寻找的众数T必定在这两个众数其一,此处可用反证法:如果T不是两个区间的众数,那么T的次数<(0,mid)区间的一半,也小于(mid+1,n-1)的一半,那么T的次数一定小于(0,n)的一半,意味T不是(0,n)区间的众数,与题意矛盾,所以T一定是两个区间之一的众数。

class Solution {
public:
    int choose(vector<int>& nums,int n,int le,int ri)
    {
        int ans=0;
        for(int i=le;i<=ri;i++)
        {
            if(nums[i]==n)
                ans++;
        }
        return ans;
    }
    int majority_element_rec(vector<int>& nums,int le,int ri)
    {
        if(le==ri)
            return nums[le];
        int mid=(le+ri)/2;
        int left_rec=majority_element_rec(nums,le,mid);
        int right_rec=majority_element_rec(nums,mid+1,ri);
        if(choose(nums,left_rec,le,ri)>(ri-le+1)/2)
            return left_rec;
        if(choose(nums,right_rec,le,ri)>(ri-le+1)/2)
            return right_rec;
        return -1;
    }
    int majorityElement(vector<int>& nums) {
        return majority_element_rec(nums,0,nums.size()-1);
    }
};

Boyer-Moore 投票算法

(1)字面理解就是候选人是众数,所以给他投票的人是最多的,赞成票肯定大于反对票,最终众数胜出。

(2)投票算法个人思路,数组中众数和其他数分成几队人在一个擂台上打架,每次擂台随机上一队的人,
如果擂台没人则留在擂台上当擂主等待挑战者;
如果是同队则一起留在擂台上;
如果不是一队的人,就干一架,因为打的比较狠,挑战者和擂台上一个人一起被抬下去;
最后,因为众数人多,所以最后站在擂台上的擂主一定是众数队,众数,永远滴神!
同时可以发现其他队不懂团结,他们的内斗消耗更有利于众数获胜(队内成员不用全部上擂台就已经没有挑战者了);
假设极端情况下数组只有两种数,众数队n+1,另一数n-1,1换1也不够打的,众数队依然可以在擂台上站到最后。

class Solution {
public:
    int majorityElement(vector<int>& nums) {
       int champoin=-1;
       int people=0;
       for(int challenger:nums)
       {
           if(challenger==champoin)
                people++;
            else
            {
                people--;
                if(people<0)
                {
                    people=1;
                    champoin=challenger;
                }
            }
       }
       return champoin;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值