一【题目类别】
- 排序
二【题目难度】
- 简单
三【题目编号】
- 414.第三大的数
四【题目描述】
- 给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
五【题目示例】
-
示例 1:
- 输入:[3, 2, 1]
- 输出:1
- 解释:第三大的数是 1 。
-
示例 2:
- 输入:[1, 2]
- 输出:2
- 解释:第三大的数不存在, 所以返回最大的数 2 。
-
示例 3:
- 输入:[2, 2, 3, 1]
- 输出:1
- 解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
六【解题思路】
- 本题如果直接对原数组排序然后找第三大的元素也可以,但是太简单,而且不符合题目进阶中的时间复杂度
- 我们可以模拟三个长度的有序队列,里面初始化a、b、c为最小值,最终我们要维持a>b>c
- 遍历数组,对于数组中的元素num
- 如果num > a,说明要将最小的替换出去,其余后移,也就是将c替换为b,b替换为a,a替换为num
- 如果a>num>b,同样将最小的替换出去,但是最大值不变,将c替换为b,b替换为num
- 如果b>num>c,只需要将最小的替换出去,将c替换为num
- 最后如果c还是初始化的最小值,说明没有第三大的元素,返回第一大的元素即可,否则返回c即可
七【题目提示】
- 1 < = n u m s . l e n g t h < = 1 0 4 1 <= nums.length <= 10^4 1<=nums.length<=104
- − 2 31 < = n u m s [ i ] < = 2 31 − 1 -2^{31} <= nums[i] <= 2^{31} - 1 −231<=nums[i]<=231−1
八【题目进阶】
- 你能设计一个时间复杂度 O ( n ) O(n) O(n) 的解决方案吗?
九【时间频度】
- 时间复杂度: O ( n ) O(n) O(n),其中 n n n为数组的长度
- 空间复杂度: O ( 1 ) O(1) O(1)
十【代码实现】
- Java语言版
package Sort;
/**
* @Author: IronmanJay
* @Description: 414.第三大的数
* @CreateTime: 2022-11-16 09:43
*/
public class p414_ThirdMaximumNumber {
public static void main(String[] args) {
int[] nums = {3, 2, 1};
int res = thirdMax(nums);
System.out.println("res = " + res);
}
public static int thirdMax(int[] nums) {
long a = Long.MIN_VALUE;
long b = Long.MIN_VALUE;
long c = Long.MIN_VALUE;
for (int num : nums) {
if (num > a) {
c = b;
b = a;
a = num;
} else if (a > num && num > b) {
c = b;
b = num;
} else if (b > num && num > c) {
c = num;
}
}
return c == Long.MIN_VALUE ? (int) a : (int) c;
}
}
- C语言版
#include<stdio.h>
#include<limits.h>
int thirdMax(int* nums, int numsSize)
{
long a = LONG_MIN;
long b = LONG_MIN;
long c = LONG_MIN;
for (int i = 0; i < numsSize; i++)
{
int num = nums[i];
if (num > a)
{
c = b;
b = a;
a = num;
}
else if (a > num && num > b)
{
c = b;
b = num;
}
else if (b > num && num > c)
{
c = num;
}
}
return c == LONG_MIN ? (int)a : (int)c;
}
/*主函数省略*/
十一【提交结果】
-
Java语言版
-
C语言版