前言
洛谷随机到一到普及-,被干碎了,看了题解才发现这个做法,非常巧妙,来csdn 记录一下
题目链接
洛谷
一、题目描述
一共有 n 个正整数 ai,找其中的众数,这个众数出现次数超过了一半。
输入格式 第一行一个整数 n,表示数的个数。
第二行 n 个正整数 ai。
输出格式 一行一个整数,表示众数。
输入样例
5
2 3 3 3 3
输出样例
3
二、思路
这题丧心病狂的内存,导致无法暴力开哈希表或者排序后输出排n/2位置的数。
那我们怎么做呢?
在这里我们引出摩尔投票法。
首先应该知道的是,
摩尔投票法找的其实不是众数,而是占一半以上的数。
当数组没有超过一半的数,则可能返回非众数。
比如【1, 1, 2, 2, 2, 3, 3】,最终返回3。
我们可以把数分成两类,一类是众数,一类是其他数。
如果两类中的数1对1互相抵消,那么最后剩下来的数,不管剩多少个,都一定是出现次数大于n/2的那个数。
这是一个打擂台的过程,不同的数双双暴毙,下一对上场。
那么我们的算法就显而易见了:
只需以下的5个步骤
1、建一个变量ans存储当前找到的众数,建一个变量sum存储当前众数的数量。
2、新加入一个数。
3、如果和ans相同,即和当前找到的众数相同,sum加1。
4、如果cnt=0,即没有找到众数,则把新数作为众数,即ans等于新数,sum等于1。
5.、如果不同,那么sum减1,即把当前的众数抵消掉一个。
输出ans
代码
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e6+5 ;
int main()
{
int n;
int ans;
int sum=0;
int x;
scanf("%d",&n);
for(int i=0;i<n;++i){
scanf("%d",&x);
if(x==ans){
sum++;
}
else if(sum==0){
ans=x;
sum++;
}
else if(sum!=0){
sum--;
}
}
printf("%d\n",ans);
return 0;
}
华丽结束~~