版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37969433/article/details/82818755
问题描述
已知一个整数序列A=(a0,a1,…,an-1),其中0≤ai<n(0≤i<n)。若存在ap1=ap2=…=apm=x且m>n/2(0≤pk<n,1≤k≤m),则称x为A的主元素。例如A=(0,5,5,3,5,7,5,5),则5为主元素;又如A=(0,5,5,3,5,1,5,7),则A中没有主元素。
假设A中的n个元素保存在一个一维数组中,请设计一个尽可能高效的算法,找出A的主元素。若存在主元素,则输出该元素;否则输出-1。
实现算法
方法一
对一个序列升序排列,遍历这个序列,m记录遍历到的值,count记录该值出现的次数。如果A[i]与m相等,则count++,否则count=1,m=A[i]。直至出现count>len/2的情况,返回这个m值。如遍历结束,即说明没有主元素,则返回-1.
方法二
对一个乱序序列,遍历这个序列,m记录遍历到的值,count记录该值出现的次数。如果A[i]与m相等,则count++,否则count–;count减为0时,则令m=A[i],count=1,;直至遍历结束。
再遍历一次,统计m出现的次数,若大于len/2,如返回m,否则返回-1.
具体代码
方法一
#include<stdio.h>
/**
冒泡法对s进行升序排列
*/
void Order(int s[],int len){
int sorted = 1;
int temp;
for(int j=0;j<len-1;j++) { //循环次数 每完成一次 沉入底部一个数
sorted = 1; //每一次开始 默认已经排好序
for(int i=0;i<len-1-j;i++) {
if(s[i] > s[i+1]) {
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
sorted = 0; //还没有排好序
}
}
if(sorted) { //确实已经排好序了
break; //不再继续循环
}
}
}
/**
对排序后的数组查找主元素
*/
int FindMajor(int s[],int len){
int m=s[0],count=0;
for(int i=0;i<len;i++){
if(m==s[i]){
count++;
}else{
count=1;
m = s[i];
}
if(count>len/2) return m;
}
return -1;
}
void main(){
int s[] = {4,1,5,1,2,5,3,5,5,5,5};
Order(s,11);
printf("%d\n",FindMajor(s,11));
}
方法二
#include<stdio.h>
int FindMajor2(int s[],int len){
int m = s[0],count=0;
for(int i=0;i<len;i++){
if(s[i]==m){
count++;
}else{
if(count>0) count--;
else{
m = s[i];
count = 1;
}
}
}
count=0;
for(int i=0;i<len;i++){
if(s[i]==m){
count++;
}
}
if(count>len/2)return m;
else return -1;
}
void main(){
int s[] = {4,1,5,1,2,5,3,5,5,5,5};
Order(s,11);
printf("%d\n",FindMajor2(s,11));
}