leetcode.169(求众数)

Q:给定一个大小为 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>hashmap;
        int i=0,result;
        int n=nums.size()/2;
        for(vector<int>::iterator iter =nums.begin();iter!=nums.end();iter++)
        {
            if(hashmap.find(*iter)!=hashmap.end())
                hashmap[*iter]+=1;
            else
                hashmap.insert(make_pair(*iter,1));
        }
        for(map<int,int>::iterator iter1=hashmap.begin();iter1!=hashmap.end();iter1++)
        {
            if((iter1->second)>n){
                 result= iter1->first;
                 return result;
            }
            else result=0;
        }  
       return result; 
    }
};

在这里插入图片描述运行速度很慢。

可以使用摩尔投票法解决这个问题:
摩尔投票法原理很简单:

在每一轮投票过程中,从数组中找出一对不同的元素,将其从数组中删除。这样不断的删除直到无法再进行投票,如果数组为空,则没有任何元素出现的次数超过该数组长度的一半。如果只存在一种元素,那么这个元素则可能为目标元素。
那么有没有可能出现最后有两种或两种以上元素呢?根据定义,这是不可能的,因为如果出现这种情况,则代表我们可以继续一轮投票。因此,最终只能是剩下零个或一个元素。

在这道题里,可以先假定第一个数是众数,同时设置一个计数器,遇到相同的数字就+1 ,遇到不同的数字就-1。当count==0时,说明到目前为止,没有找到众数。

因为题目中说,一定存在众数,所以后面没有遍历到的数中,一定有众数。那就将count==0的数设为众数,继续之前的操作,此时,count=1。

输入: [2,2,1,1,1,2,2]
输出: 2
以上面这个数组为例,开始假定2为众数,当遍历到第二个1时,count=0。此时,就以这个1为众数,继续遍历。当遍历到最后一个2时,count为0,也就是说,1不是众数,由于此时还没有找到众数,所以2一定是众数。
代码如下:

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

还有一种分治的方法解题,就是将数组分成几个子数组。分别寻找众数,如果几个数组找的众数相同,那这个数就是众数,如果找的不同,再重新遍历或者看各个数组中出现的频率。具体可以参考这个文章:
分治求众数
但是测试了一下,时间比较慢。

所以应该是摩尔投票法比较好用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值