小鱼刷leetcode---414. 第三大的数

86 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第8天,点击查看活动详情

一 描述

414. 第三大的数 - 力扣(LeetCode) (leetcode-cn.com)

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

 

示例 1:

输入:[3, 2, 1]
输出:1
解释:第三大的数是 1

示例 2:

输入:[1, 2]
输出:2
解释:第三大的数不存在, 所以返回最大的数 2

示例 3:

输入:[2, 2, 3, 1]
输出:1
解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。
此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1

提示:

  • 1 = nums.length = 10^4
  • -2^31 = nums[i] = 2^31 - 1

二 分析

需要满足时间复杂度 O(n) ,也就是最多遍历一次数组,那么设定3个变量,遍历一次数组,找出最大的3个,然后取第3大的即可。 期间要注意可能3个变量中,有2个或1个不会被赋值(数组只有1~2个元素,或重复元素的情况),变量可以使用 Integer,当没有赋值就为null。 返回数据时,判断如果第3大的数不为 null 则返回,否则返回最大的。

三 答案

class Solution {
    public int thirdMax(int[] nums) {
        Integer max1 = null;
        Integer max2 = null;
        Integer max3 = null;

        for (int i = 0; i  nums.length; i ++) {
            if (max1 == null  nums[i]  max1) {
                max3 = max2;
                max2 = max1;
                max1 = nums[i];
            } else if (max2 == null  nums[i]  max2) {
                if (nums[i] != max1) {
                    max3 = max2;
                    max2 = nums[i];
                }
            } else if (max3 == null  nums[i]  max3) {
                if (nums[i] != max2) {
                    max3 = nums[i];
                }
            }
        }

        if (max3 != null) {
            return max3;
        } else {
            return max1;
        }
    }
}

四 总结

对于这类第k大或第k小问题,通常都可以构大根堆或小根堆来实现,只不过这里多了一步去重操作 本题可以构建3个元素的小根堆,堆顶元素就是第3大元素

参考

【ACM金牌题解】set & 观察变量 编程熊 - 第三大的数 - 力扣(LeetCode) (leetcode-cn.com)