自用笔记54——qsort()最小值溢出

给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。

示例 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)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值