主元素问题是一道非常经典的著名的问题,乍一看很简单,也很容易写出来,但越往后越难。
问题描述:给定一个长度为n的序列,若当中有数出现的次数>50%,输出这个数;否则输出NO。
还是先上数据:
7
3 3 1 1 3 2 3
输出是:
3
有什么好的方法吗?
建议你花时间先想一想
好啦,开始讲解。
Algorithm1:
将数组进行排序,堆排序或者快速排序,然后找出n/2+1那个位置的数。然后再扫一遍,统计这个数出现的次数。若该次数>n/2,那么这个数就是结果,否则输出NO。
原理:如果有数出现的次数>n/2,那么排序后,它一定会出现在n/2+1的位置上(想一想为什么)。
时间复杂度:O(N log N)
空间复杂度:O(N)
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> using namespace std; int n,a[1005],i,cnt; int main() { scanf("%d",&n); for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a+1,a+n+1); for(i=1;i<=n;i++) if(a[i]==a[n/2+1]) cnt++; if(cnt>n/2) printf("%d",a[n/2+1]); else printf("NO"); return 0; }