414. 第三大的数

414. 第三大的数

一、题目

给定一个非空数组,返回此数组中第三大的数。如果不存在,则返回数组中最大的数。要求算法时间复杂度必须是O(n)。

示例 1:

输入: [3, 2, 1]

输出: 1

解释: 第三大的数是 1.

示例 2:

输入: [1, 2]

输出: 2

解释: 第三大的数不存在, 所以返回最大的数 2 .

示例 3:

输入: [2, 2, 3, 1]

输出: 1

解释: 注意,要求返回第三大的数,是指第三大且唯一出现的数。
存在两个值为2的数,它们都排第二。

二、题解

  • 数组长度为1——返回最大值
  • 数组长度为2——返回二者中较大的一个
  • 数组长度>=3——不断更新最大值,第二大的值,第三大的值
class Solution {
    public int thirdMax(int[] nums) {

        int max = Integer.MIN_VALUE;
        int secondMax = Integer.MIN_VALUE;
        int thirdMax = Integer.MIN_VALUE;
        int count = 0;//用计数器记录出现不同数的个数
        boolean key = true;

        switch (nums.length) {
            case 1:
                return nums[0];
            case 2:
                return Math.max(nums[0], nums[1]);
            default:
                //由于这个例子[1,-2147483648,2]不会进入下面if-else if结构
                //因为max,secondMax,thirdMax的初始值都是-2147483648,不需要更新值
                //但是出现了-2147483648这个数,计数器需要加1次,用key关闭
                for (int i = 0; i < nums.length; i++) {
                    if (nums[i] == Integer.MIN_VALUE && key) {
                        count++;
                        key = false;
                    }
                    if (nums[i] > max) {
                        //出现新的最大值,更新max,secondMax,thirdMax
                        thirdMax = secondMax;
                        secondMax = max;
                        max = nums[i];
                        count++;
                    } else if (nums[i] < max && nums[i] > secondMax) {
                        //出现新的第二大值,更新secondMax,thirdMax
                        thirdMax = secondMax;
                        secondMax = nums[i];
                        count++;
                    } else if (nums[i] < max && nums[i] < secondMax && nums[i] > thirdMax) {			 
                        //出现新的第三大值,更新thirdMax
                        thirdMax = nums[i];
                        count++;
                    }
                    //出现比第三大数还小的值,或和已有数相等的值,都不更新值,计数器不累加
                }
                return count < 3 ? max : thirdMax;
        }
    }
}
  • 关于值更新

    for (int i = 0; i < nums.length; i++) {
        if(nums[i]>max) {
            thirdMax = secendMax;
          secendMax = max;
            max = nums[i];
        } else if (nums[i]>secendMax) {
            thirdMax = secendMax;
            secendMax = nums[i];
      } else if (nums[i]>thirdMax) {
            thirdMax = nums[i];
        }
    }
    //采用这种判断条件出现重复的数字也会进行值更新,也即是说max,secondMAx,thirdMax的值可能是相等
    //如例[1000,1000,1000]或[2,2,3,1]
    //因为第1轮max<1000,更新max的值
    //第2轮max=1000,secondMax仍<1000,更新secondMax的值
    //第3轮max=1000、secondMax=1000,thirdMax仍<1000,更新thirdmax的值,因此不能采用此条件
    
  • 也可以考虑使用定义long类型的Max、secondMax、thirdMax,这样Long.MIN_VALUE=-9223372036854775808就会小于-2147483648,就不需要考虑出现的数值为无穷小时的情况了

  • 其他示例

    输入: [1,-2147483648,2]
    输出: 1
    
    输入: [-2147483648,-2147483648,-2147483648,-2147483648,1,1,1]
    输出: 1
    
    输入: [5,2,4,1,3,6,0]
    输出: 3
    
  • 执行用时:1 ms, 在所有 Java 提交中击败了96.50%的用户

  • 内存消耗:38.4 MB, 在所有 Java 提交中击败了90.68%的用户

posted @ 2020-10-17 22:17  球球z  阅读(129)  评论(0)    收藏  举报