问题描述
给定n个正整数,找出它们中出现次数最多的数。如果这样的数有多个,请输出其中最小的一个。
输入
输入的第一行只有一个正整数n(1 ≤ n ≤ 1000),表示数字的个数。输入的第二行有n个整数S1, S2, …, Sn (1 ≤ Si ≤ 10000, 1 ≤ i ≤ n)。相邻的数用空格分隔。
输出
输出这n个次数中出现次数最多的数。如果这样的数有多个,输出其中最小的一个。
样例
输入样例
6
10 1 10 20 30 20
输出样例
10
算法思想与AC代码
思路一:桶排序(或者理解为hash散列)
#include <stdio.h>
int main()
{
int i,n,number;
int count; //count记录当前元素在当前已有的列表中出现的次数
int max; //max记录当前列表中出现次数最多的数的出现次数
int min; //min记录当前列表中出现次数最多的数中的最小的数
static int num[10000]={0}; //建立元素到桶的映射规则(构建hash散列)
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&number);
count=(num[number-1]++);
if(i==0) max=count,min=number; //i等于0时,初始化max和min
else
{
//若当前元素的出现次数比上一次记录的出现次数最多的数多,更新max和min
if(count>max) max=count,min=number;
//若当前元素的出现次数等于上一次记录的出现次数最多的数,并且该数比上一次记录的出现次数最多的数小,更新min
else if(count==max&&number<min) min=number;
}
}
printf("%d\n",min);
return 0;
}
思路二:遍历查找
#include <stdio.h>
//num[i][0]存储列表中出现的数,num[i][1]记录该数在当前列表中出现的次数
static int num[1001][2]={0};
int main()
{
int i,j;
int n,number;
int max; //max记录当前列表中出现次数最多的数的出现次数
int min; //min记录当前列表中出现次数最多的数中的最小的数
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&number);
for(j=0;num[j][0]!=0;j++)
{
if(num[j][0]==number) break; //若当前列表中有该元素,跳出循环
}
if(num[j][0]==0) num[j][0]=number; //若当前列表中没有该元素,添加该元素到列表尾部
num[j][1]++; //当前元素出现的次数加一
if(i==0) max=num[0][1],min=num[0][0]; //i等于0时,初始化max和min
else
{
//若当前元素的出现次数比上一次记录的出现次数最多的数多,更新max和min
if(num[j][1]>max) max=num[j][1],min=num[j][0];
//若当前元素的出现次数等于上一次记录的出现次数最多的数,并且该数比上一次记录的出现次数最多的数小,更新min
else if(num[j][1]==max&&num[j][0]<min) min=num[j][0];
}
}
printf("%d\n",min);
return 0;
}