加载中...
414-第三大的数(Third Maximum Number)
发表于:2021-12-03 | 分类: 简单
字数统计: 337 | 阅读时长: 1分钟 | 阅读量:

原文链接: https://leetcode-cn.com/problems/third-maximum-number

英文原文

Given an integer array nums, return the third distinct maximum number in this array. If the third maximum does not exist, return the maximum number.

 

Example 1:

Input: nums = [3,2,1]
Output: 1
Explanation:
The first distinct maximum is 3.
The second distinct maximum is 2.
The third distinct maximum is 1.

Example 2:

Input: nums = [1,2]
Output: 2
Explanation:
The first distinct maximum is 2.
The second distinct maximum is 1.
The third distinct maximum does not exist, so the maximum (2) is returned instead.

Example 3:

Input: nums = [2,2,3,1]
Output: 1
Explanation:
The first distinct maximum is 3.
The second distinct maximum is 2 (both 2's are counted together since they have the same value).
The third distinct maximum is 1.

 

Constraints:

  • 1 <= nums.length <= 104
  • -231 <= nums[i] <= 231 - 1

 

Follow up: Can you find an O(n) solution?

中文题目

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

 

示例 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

 

进阶:你能设计一个时间复杂度 O(n) 的解决方案吗?

通过代码

高赞题解

Set 去重 + 排序

题目要求返回含重复元素的数组 $nums$ 中的第三大数。

一个朴素的做法是,先使用 Set 对重复元素进行去重,然后对去重后的元素进行排序,并返回第三大的元素。

代码:

[]
class Solution { public int thirdMax(int[] nums) { Set<Integer> set = new HashSet<>(); for (int x : nums) set.add(x); List<Integer> list = new ArrayList<>(set); Collections.sort(list); return list.size() < 3 ? list.get(list.size() - 1) : list.get(list.size() - 3); } }
  • 时间复杂度:使用 Set 去重的复杂度为 $O(n)$;排序复杂度为 $O(n\log{n})$。整体复杂度为 $O(n\log{n})$
  • 空间复杂度:$O(n)$

有限变量 + 遍历

经典的找数组次大值的做法是使用两个变量 ab 分别存储遍历过程中的最大值和次大值。

假设当前遍历到的元素为 $x$,当满足如下条件时,考虑更新 a 或者 b:

  1. 当 $x > a$ 时,说明最大值被更新,同时原来的最大值沦为次大值。即有 $b = a; a = x;$
  2. 在条件 $1$ 不满足,且有$x > b$ 时,此时可以根据是否有「严格次大值」的要求,而决定是否要增加 $x < a$ 的条件:
    • 不要求为「严格次大值」:直接使用 $x$ 来更新 b,即有 $b = x$;
    • 当要求为「严格次大值」: 此时需要满足 $x < a$ 的条件,才能更新 b

回到本题,同理我们可以使用 abc 三个变量来代指「最大值」、「严格次大值」和「严格第三大值」。

从前往后遍历 $nums$,假设当前元素为 $x$,对是否更新三者进行分情况讨论(判断优先级从上往下):

  1. $x > a$,说明最大值被更新,将原本的「最大值」和「次大值」往后顺延为「次大值」和「第三大值」,并用 $x$ 更新 a
  2. $x < a$ 且 $x > b$,说明次大值被更新,将原本的「次大值」往后顺延为「第三大值」,并用 $x$ 更新 b
  3. $x < b$ 且 $x > c$,说明第三大值被更新,使用 $x$ 更新 c

起始时,我们希望使用一个足够小的数来初始化 abc,但由于 $num[i]$ 的范围为 $[-2^{31}, 2^{31} - 1]$,因此需要使用 long 来进行代替。

返回时,通过判断第三大值是否为初始化时的负无穷,来得知是否存在第三大值。

代码:

[]
class Solution { long INF = (long)-1e18; public int thirdMax(int[] nums) { long a = INF, b = INF, c = INF; for (int x : nums) { if (x > a) { c = b; b = a; a = x; } else if (x < a && x > b) { c = b; b = x; } else if (x < b && x > c) { c = x; } } return c != INF ? (int)c : (int)a; } }
  • 时间复杂度:$O(n)$
  • 空间复杂度:$O(1)$

其他

国庆题太简单?

不如来做一道热乎的 背包问题求方案数(公主号「背包专题」的第 $20$ 讲,共 $23$ 讲)🍭🍭🍭

或是加练如下「模拟」或「排序」题目 🍭🍭🍭

1. 模拟

题目 题解 难度 推荐指数
1. 两数之和 LeetCode 题解链接 简单 🤩🤩🤩🤩🤩
2. 两数相加 LeetCode 题解链接 中等 🤩🤩🤩🤩🤩
5. 最长回文子串 LeetCode 题解链接 中等 🤩🤩🤩🤩🤩
6. Z 字形变换 LeetCode 题解链接 中等 🤩🤩🤩
7. 整数反转 LeetCode 题解链接 简单 🤩🤩🤩
8. 字符串转换整数 (atoi) LeetCode 题解链接 中等 🤩🤩🤩
12. 整数转罗马数字 LeetCode 题解链接 中等 🤩🤩
13. 罗马数字转整数 LeetCode 题解链接 简单 🤩🤩
14. 最长公共前缀 LeetCode 题解链接 简单 🤩🤩🤩🤩
31. 下一个排列 LeetCode 题解链接 中等 🤩🤩🤩
38. 外观数列 LeetCode 题解链接 简单 🤩🤩
43. 字符串相乘 LeetCode 题解链接 中等 🤩🤩🤩🤩
58. 最后一个单词的长度 LeetCode 题解链接 中等 🤩🤩🤩🤩
59. 螺旋矩阵 II LeetCode 题解链接 中等 🤩🤩🤩🤩
65. 有效数字 LeetCode 题解链接 困难 🤩🤩🤩
68. 文本左右对齐 LeetCode 题解链接 困难 🤩🤩🤩
73. 矩阵置零 LeetCode 题解链接 中等 🤩🤩🤩🤩
165. 比较版本号 LeetCode 题解链接 中等 🤩🤩🤩🤩
166. 分数到小数 LeetCode 题解链接 中等 🤩🤩🤩🤩
168. Excel表列名称 LeetCode 题解链接 简单 🤩🤩🤩
171. Excel表列序号 LeetCode 题解链接 简单 🤩🤩🤩
190. 颠倒二进制位 LeetCode 题解链接 简单 🤩🤩🤩
233. 数字 1 的个数 LeetCode 题解链接 困难 🤩🤩🤩🤩
263. 丑数 LeetCode 题解链接 简单 🤩🤩
284. 顶端迭代器 LeetCode 题解链接 中等 🤩🤩🤩🤩
345. 反转字符串中的元音字母 LeetCode 题解链接 简单 🤩🤩🤩
405. 数字转换为十六进制数 LeetCode 题解链接 简单 🤩🤩🤩🤩
413. 等差数列划分 LeetCode 题解链接 中等 🤩🤩🤩🤩
414. 第三大的数 LeetCode 题解链接 中等 🤩🤩🤩🤩
443. 压缩字符串 LeetCode 题解链接 中等 🤩🤩🤩🤩
451. 根据字符出现频率排序 LeetCode 题解链接 中等 🤩🤩🤩🤩
457. 环形数组是否存在循环 LeetCode 题解链接 中等 🤩🤩🤩🤩
482. 密钥格式化 LeetCode 题解链接 简单 🤩🤩🤩🤩
528. 按权重随机选择 LeetCode 题解链接 中等 🤩🤩🤩🤩
541. 反转字符串 II LeetCode 题解链接 简单 🤩🤩🤩🤩🤩
551. 学生出勤记录 I LeetCode 题解链接 简单 🤩🤩🤩
566. 重塑矩阵 LeetCode 题解链接 简单 🤩🤩🤩
645. 错误的集合 LeetCode 题解链接 简单 🤩🤩🤩
726. 原子的数量 LeetCode 题解链接 困难 🤩🤩🤩🤩
766. 托普利茨矩阵 LeetCode 题解链接 简单 🤩🤩🤩
867. 转置矩阵 LeetCode 题解链接 简单 🤩🤩🤩🤩
896. 单调数列 LeetCode 题解链接 简单 🤩🤩🤩🤩
1047. 删除字符串中的所有相邻重复项 LeetCode 题解链接 简单 🤩🤩🤩🤩
1104. 二叉树寻路 LeetCode 题解链接 中等 🤩🤩🤩
1436. 旅行终点站 LeetCode 题解链接 简单 🤩🤩🤩🤩🤩
1480. 一维数组的动态和 LeetCode 题解链接 简单 🤩🤩🤩🤩🤩
1486. 数组异或操作 LeetCode 题解链接 简单 🤩🤩🤩
1583. 统计不开心的朋友 LeetCode 题解链接 中等 🤩🤩🤩🤩
1646. 获取生成数组中的最大值 LeetCode 题解链接 简单 🤩🤩🤩🤩
1720. 解码异或后的数组 LeetCode 题解链接 简单 🤩🤩🤩
1736. 替换隐藏数字得到的最晚时间 LeetCode 题解链接 简单 🤩🤩🤩🤩
1743. 从相邻元素对还原数组 LeetCode 题解链接 中等 🤩🤩🤩🤩
1748. 唯一元素的和 LeetCode 题解链接 简单 🤩🤩
1763. 最长的美好子字符串 LeetCode 题解链接 简单 🤩🤩🤩
1834. 单线程 CPU LeetCode 题解链接 中等 🤩🤩🤩🤩
1893. 检查是否区域内所有整数都被覆盖 LeetCode 题解链接 简单 🤩🤩🤩🤩
1894. 找到需要补充粉笔的学生编号 LeetCode 题解链接 中等 🤩🤩🤩🤩
面试题 10.02. 变位词组 LeetCode 题解链接 中等 🤩🤩🤩🤩

注:以上目录整理来自 wiki,任何形式的转载引用请保留出处。

2. 排序

题目 题解 难度 推荐指数
41. 缺失的第一个正数 LeetCode 题解链接 困难 🤩🤩🤩
220. 存在重复元素 III LeetCode 题解链接 中等 🤩🤩🤩
414. 第三大的数 LeetCode 题解链接 中等 🤩🤩🤩🤩
448. 找到所有数组中消失的数字 LeetCode 题解链接 简单 🤩🤩🤩
524. 通过删除字母匹配到字典里最长单词 LeetCode 题解链接 中等 🤩🤩🤩🤩
581. 最短无序连续子数组 LeetCode 题解链接 中等 🤩🤩🤩🤩
611. 有效三角形的个数 LeetCode 题解链接 中等 🤩🤩🤩🤩
645. 错误的集合 LeetCode 题解链接 简单 🤩🤩🤩
703. 数据流中的第 K 大元素 LeetCode 题解链接 简单 🤩🤩🤩
987. 二叉树的垂序遍历 LeetCode 题解链接 困难 🤩🤩🤩🤩🤩
1833. 雪糕的最大数量 LeetCode 题解链接 中等 🤩🤩🤩🤩🤩
1834. 单线程 CPU LeetCode 题解链接 中等 🤩🤩🤩🤩
1838. 最高频元素的频数 LeetCode 题解链接 中等 🤩🤩🤩
面试题 10.02. 变位词组 LeetCode 题解链接 中等 🤩🤩🤩🤩
面试题 17.14. 最小K个数 LeetCode 题解链接 中等 🤩🤩🤩🤩

注:以上目录整理来自 wiki,任何形式的转载引用请保留出处。


最后

如果有帮助到你,请给题解点个赞和收藏,让更多的人看到 ~ (“▔□▔)/

也欢迎你 关注我(公主号后台回复「送书」即可参与长期看题解学算法送实体书活动)或 加入「组队打卡」小群 ,提供写「证明」&「思路」的高质量题解。

所有题解已经加入 刷题指南,欢迎 star 哦 ~

统计信息

通过次数 提交次数 AC比率
92265 234170 39.4%

提交历史

提交时间 提交结果 执行时间 内存消耗 语言

相似题目

题目 难度
数组中的第K个最大元素 中等
上一篇:
412-Fizz Buzz
下一篇:
415-字符串相加(Add Strings)
本文目录
本文目录