Easy
题目描述
给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:nums = [3,2,1]
输出:1
解释:
第一大的数是 3 。
第二大的数是 2 。
第三大的数是 1 。
示例 2:
输入:nums = [1,2]
输出:2
解释:
第一大的数是 2 。
第二大的数是 1 。
第三大的数不存在,所以返回最大的数 2 。
示例 3:
输入:nums = [2,2,3,1]
输出:1
解释:
第一大的数是 3 。
第二大的数是 2(两个 2 都算作第二大)。
第三大的数是 1 。
提示:
1 <= nums.length <= 10^4-2^31 <= nums[i] <= 2^31 - 1
**进阶:**你能设计一个时间复杂度 O(n) 的解决方案吗?
解题思路
这道题要求找到数组中第三大的不同数字,如果不存在则返回最大值。
解法一:排序法 最直观的方法是先排序,然后找第三大的不同元素。先对数组进行降序排序,然后遍历找到第三个不同的数字。时间复杂度为 O(n log n)。
解法二:一次遍历维护三个最大值(推荐)
我们可以用三个变量来维护当前遇到的前三大的不同数字:first(最大)、second(第二大)、third(第三大)。遍历数组时:
- 如果当前数字比
first大,则更新三个变量 - 如果当前数字比
second大但不等于first,则更新second和third - 如果当前数字比
third大但不等于前两者,则更新third
需要注意的是,要使用 long 类型来避免整数溢出问题,并且初始化为 LONG_MIN。
最后检查是否找到了三个不同的数字,如果找到了返回 third,否则返回 first。
这种方法只需要一次遍历,时间复杂度为 O(n),空间复杂度为 O(1)。
代码实现
class Solution {
public:
int thirdMax(vector<int>& nums) {
long first = LONG_MIN, second = LONG_MIN, third = LONG_MIN;
for (int num : nums) {
if (num > first) {
third = second;
second = first;
first = num;
} else if (num > second && num < first) {
third = second;
second = num;
} else if (num > third && num < second) {
third = num;
}
}
return third == LONG_MIN ? first : third;
}
};
class Solution:
def thirdMax(self, nums: List[int]) -> int:
first = second = third = float('-inf')
for num in nums:
if num > first:
third, second, first = second, first, num
elif num > second and num < first:
third, second = second, num
elif num > third and num < second:
third = num
return third if third != float('-inf') else first
public class Solution {
public int ThirdMax(int[] nums) {
long first = long.MinValue, second = long.MinValue, third = long.MinValue;
foreach (int num in nums) {
if (num > first) {
third = second;
second = first;
first = num;
} else if (num > second && num < first) {
third = second;
second = num;
} else if (num > third && num < second) {
third = num;
}
}
return third == long.MinValue ? (int)first : (int)third;
}
}
var thirdMax = function(nums) {
let first = -Infinity, second = -Infinity, third = -Infinity;
for (let num of nums) {
if (num === first || num === second || num === third) continue;
if (num > first) {
third = second;
second = first;
first = num;
} else if (num > second) {
third = second;
second = num;
} else if (num > third) {
third = num;
}
}
return third === -Infinity ? first : third;
};
复杂度分析
| 算法 | 时间复杂度 | 空间复杂度 |
|---|---|---|
| 一次遍历维护三个最大值 | O(n) | O(1) |
| 排序法 | O(n log n) | O(1) |
相关题目
. Kth Largest Element in an Array (Medium)