给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。
示例 2:
输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2 。
示例 3:
输入:[2, 2, 3, 1]
输出:1
解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/third-maximum-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
/*int cmp(const void *a,const void *b)
{
return *(int *)b - *(int *)a;
}*/
int thirdMax(int* nums, int numsSize){
int i=0,j=0,flag=0,t=0,finish_flag=0;
for(i=0;i<numsSize;i++)
{
finish_flag = 0;
for(j=numsSize-1;j>i;j--)
{
if(nums[j] > nums[j-1])
{
t = nums[j];
nums[j] = nums[j-1];
nums[j-1] = t;
finish_flag = 1;
}
}
if(finish_flag != 1)
break;
}
//qsort(nums,numsSize,sizeof(nums[0]),cmp);
for(i=0;i<numsSize-1;i++)
{
if(nums[i+1] < nums[i])
flag++;
if(flag == 2)
return nums[i+1];
}
return nums[0];
}
直接用qsort()
函数会报错
研究下机制发现是被排序的数组里不能有-2147483648,哪怕是int类型的最小数值, qsort也无法对其排序,但是最大值2147483647可以直接被排序。实验之后发现就算是-2147483647也无法对其排序,但是-2147483646就可以,就很神奇。
经过尝试发现有时-2147483646也不行,但是改成-2147483645就完全没问题了, 真是奇怪他妈接小奇怪放学——奇怪到家了。
顺着这个思路就可以使用qsort()函数了,把数组中的-2147483648改成-214748364进行排序,排完后在筛选返回时将其再改为-2147483648。但是这个方法有一点不足就是如果数组里原来就有-2147483645这个元素就会引起冲突,但是还可以通过改进使其合理,可惜题目中的用例没有我所说的特殊情况,直接改然后用qsort()可以节省大量时间,qsort()还是比冒泡排序法快不少。
int cmp(const void *a,const void *b)
{
return *(int *)b - *(int *)a;
}
int thirdMax(int* nums, int numsSize){
int i=0,flag=0,finish_flag=0;
//int j=0,t=0;
for(i=0;i<numsSize;i++)
{
if(nums[i] == pow(-2,31))
{
finish_flag = 1;
nums[i] = -2147483645;
}
}
/*for(i=0;i<numsSize;i++)
{
finish_flag = 0;
for(j=numsSize-1;j>i;j--)
{
if(nums[j] > nums[j-1])
{
t = nums[j];
nums[j] = nums[j-1];
nums[j-1] = t;
finish_flag = 1;
}
}
if(finish_flag != 1)
break;
}*/
qsort(nums,numsSize,sizeof(nums[0]),cmp);
for(i=0;i<numsSize-1;i++)
{
if(nums[i+1] < nums[i])
flag++;
if(flag == 2)
{
if(finish_flag == 1 && nums[i+1] == -2147483645)
return nums[i+1]-3;
else
return nums[i+1];
}
}
if(finish_flag == 1 && nums[0] == -2147483645)
return nums[0]-3;
else
return nums[0];
}
但是仔细想想好像不用将数组排序,只要找出最大的三个数就行了,将数组全部排序好像有点费时间,直接用三个变量遍历判断,将最大的三个数放在其中
int thirdMax(int* nums, int numsSize){
//由于题目没给范围,所以先将存储前三大的数的变量设置成最小值
int max = INT_MIN,two = INT_MIN,three = INT_MIN,cnt = 1;
//然后再用3个变量来判断数组中是否有三个不同的值(先将他们都赋值为数组第一个数)
int temp1 = nums[0],temp2 = nums[0],temp3 = nums[0];
//循环找到前三大的数
for(int i = 0;i < numsSize;i++)
{
//这里我们要保证temp2和temp3都与temp1不相同
if(nums[i] != temp1)
{
if(temp1 != temp2)
{
temp3 = nums[i];
}
else
{
temp2 = nums[i];
}
}
//如果找到一个更大的数,则将当前的max变成two,two变成three
if(nums[i] > max)
{
three = two;
two = max;
max = nums[i];
}
//如果这个数不是更大的数,则与第二大的数比较
else if(nums[i] < max && nums[i] > two)
{
three = two;
two = nums[i];
}
//否则再与第三大的数比较
else if(nums[i] < max && nums[i] < two && nums[i] > three) three = nums[i];
}
if(temp2 == temp3 || temp1 == temp3) return max;
else return three;
}
作者:gy1768532
链接:https://leetcode-cn.com/problems/third-maximum-number/solution/c-414-di-san-da-de-shu-by-gy1768532/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。