题目
输入一个数组,然后求出第二大的数。不能使用排序,时间复杂度O(n),空间复杂度O(1)。(假设数组元素个数不超过106 ,都是整型)
思路
分为两种情况,第二大的数存在与不存在。
- 读数组,如果元素个数小于2,那么肯定不存在。
- 如果所有元素相等,亦不存在。
- 从前往后找到两个值不同的数,一个为最大值MAX的初始值,一个为第二大的数SecMAX的初始值。
- 继续遍历数组,与MAX比较,如果大于MAX,就把MAX的值给SecMAX,该值给MAX;如果小于MAX,再与SecMAX比较。
代码
#include <stdio.h>
const int MaxSize = 1e6;
int main()
{
int Size = 0, num, a[MaxSize];//Size记录元素个数,num暂存输入的数
printf("请输入数组:");
while(scanf("%d", &num) != EOF) //读数组
{
a[Size++] = num;
}
if(Size < 2)//数组大小小于2,肯定没有第二大的数
{
printf("不存在第二大的数\n");
}else
{
int i = 1;
while(a[i] == a[i-1] && i < Size)//依次寻找两个值不同的数,防止越界
{
++i;
}
if(Size == i) //所有元素相等
{
printf("不存在第二大的数\n");
}else{
int MAX, SecMAX;
if(a[i] > a[i-1])
{
MAX = a[i];
SecMAX = a[i-1];
}else
{
MAX = a[i-1];
SecMAX = a[i];
}
for(++i; i < Size; ++i)//接着从i+1的位置开始往后找
{
if(a[i] > MAX)//排除掉a[i]与MAX相等的情况
{
SecMAX = MAX;
MAX = a[i];
}else if(a[i] < MAX)
{
if(a[i] > SecMAX)
{
SecMAX = a[i];
}
}
}
printf("第二大的数为:%d\n", SecMAX);
}
}
return 0;
}