题目描述
题目链接:414.第三大的数
给你一个非空数组,返回此数组中第三大的数
。如果不存在,则返回数组中最大的数。
示例 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
解题核心
因为不考虑重复元素,所以要想办法去重或者重复元素不进行判断
解法一:排序+遍历
先将数组进行排序,然后记录一共有多少种不重复元素,最后倒叙遍历查找第三大的数
public int thirdMax(int[] nums) {
Arrays.sort(nums);
//计算不重复元素个数
int num = 1;
int temp = nums[0];
for (int i : nums) {
if (temp != i) {
temp = i;
num++;
}
}
//寻找第三大元素
int res = nums[nums.length - 1];
int index = 2;
for (int i = nums.length - 1; i >= 0; i--) {
if (res != nums[i] && index > 0) {
res = nums[i];
index--;
}
}
return num >= 3 ? res : nums[nums.length - 1];
}
优化一下就是下面的写法,时间复杂度没变只是看上去整洁了一些
public int thirdMax(int[] nums) {
Arrays.sort(nums);
int num = 1;
int res = nums[nums.length - 1];
for (int i = nums.length - 1; i >= 0; i--) {
if (res != nums[i] && num < 3) {
res = nums[i];
num++;
}
}
return num == 3 ? res : nums[nums.length - 1];
}
解法二:set去重+排序
使用set
去从后,将其转换成数组排序,然后按要求输出即可
public int thirdMax(int[] nums) {
HashSet<Integer> set = new HashSet<>();
for (int i : nums) {
set.add(i);
}
Object[] array = set.toArray();
Arrays.sort(array);
return (int) (set.size() >= 3 ? array[set.size() - 3] : array[set.size() - 1]);
解法三:类优先级队列
设置一个长度为3
的数组(一定要用int下边界初始化,因为数组元素可能会出现负数,防止被默认初始化的0覆盖),然后依次修改数组元素使得数组结果为前三大的数
public int thirdMax(int[] nums) {
int[] num = new int[] {-2147483648,-2147483648,-2147483648};//min normal max
HashSet<Integer> set = new HashSet<>();
for (int i : nums) {
set.add(i);
if((i == num[2])||(i == num[1])||(i == num[0])) {
continue;
}
if (i > num[2]) {
num[0] = num[1];
num[1] = num[2];
num[2] = i;
} else if (i > num[1]) {
num[0] = num[1];
num[1] = i;
} else if (i > num[0]) {
num[0] = i;
}
}
return set.size() >= 3 ? num[0] : num[2];
}