求最大、次大和第三大的值
本题目要求读入n个整数,要求用最少的比较次数,输出它们的最大值、第2大的值和第3大的值。例如,对于13 13 1 10 34 10这6个数,最大值为34,第2大的值为13,第3大的值为10。
输入格式:
输入有两行。第一行为整数个数n(≤1 000 000),第二行给出n个以空格分隔的整数。
输出格式:
对每一组输入,在一行中输出最大值、第2大的值和第3大的值值,中间以一个空格分隔,但行尾没有多余空格。
如果输入数据不足三个,则输出“Invalid Input”。
如果没有第3大的值,则输出“There is no third largest element”。
如果没有第2大和第3大的值,则输出“There is no second largest and third largest element”。
输入样例:
6
13 13 1 10 34 10
输出样例:
34 13 10
第一眼看到这道题纠结了好久,题目中说用最少的比较次数来完成。既然求三个值,脑子中的第一反应是遍历,但出现了一个错误想法,即遍历的时间复杂度是O(N3),其实不然,它只是分三次进行遍历,时间复杂度仍为O(N),代码如下:
代码块:
#include<stdio.h>
#include<stdlib.h>
# define MAXSIZE 100000000
#define NUMSIZE -10000000 //宏定义最大值、次大值和第三大值的初始值
int main(){
int *a=(int *)malloc(MAXSIZE*sizeof(int));//动态申请数组
int i;
int n;//数组的长度
scanf("%d",&n);
//输入元素个数少于3个,不符合题目要求
if(n<3){
printf("Invalid Input");
return 0;
}
for(i=0;i<n;i++){
scanf("%d",&a[i]);
}
int first=NUMSIZE;//最大值
int second=NUMSIZE;//次大值
int third=NUMSIZE;//第三大值
//找最大值,如果数组中第i个元素的值大于first,则更新first的值
for(i=0;i<n;i++){
if(first<a[i]){
first=a[i];
}
}
//找次大值,同上
for(i=0;i<n;i++){
if(second<a[i]&&a[i]!=first){
second=a[i];
}
}
if(second==NUMSIZE){
printf("There is no second largest and third largest element");
return 0;
}
//找第三大值
for(i=0;i<n;i++){
if(third<a[i]&&a[i]!=first&&a[i]!=second){
third=a[i];
}
}
if(third==NUMSIZE){
printf("There is no third largest element");
return 0;
}
printf("%d %d %d",first,second,third);
free(a);//释放内存
return 0;
}
程序比较简单,问题在于卡在了时间复杂度上,总觉得它的时间复杂度是O( N 3 N^3 N3),想错了,哦NO!!!