给你一个非空数组,返回此数组中 第三大的数 。如果不存在,则返回数组中最大的数。
示例 1:
输入:[3, 2, 1] 输出:1 解释:第三大的数是 1 。
示例 2:
输入:[1, 2] 输出:2 解释:第三大的数不存在, 所以返回最大的数 2 。
示例 3:
输入:[2, 2, 3, 1] 输出:1 解释:注意,要求返回第三大的数,是指在所有不同数字中排第三大的数。 此例中存在两个值为 2 的数,它们都排第二。在所有不同数字中排第三大的数为 1 。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/third-maximum-number
思路一:
1.先直接对数组全部数据进行排序,可以采用:
Arrays.sort(nums);
2.排序后数组从小到大排列,最大值为数组最后一个元素。从后向前遍历数组,找到小于最大值的第一个数,它就是第二大数,剩下的数和第二大数比较,小于它的第一个数就是第三大数。
class Solution {
public int thirdMax(int[] nums) {
Arrays.sort(nums);
int maxNum = nums[nums.length - 1];
int secondMaxNumIndex = -1;
for (int i=nums.length-2; i>=0; i--)
{
if (secondMaxNumIndex != -1)
{
if(nums[i] < nums[secondMaxNumIndex])
return nums[i];
}
else
{
if(nums[i] < maxNum)
secondMaxNumIndex = i;
}
}
return maxNum;
}
}
问题:耗时较大,排序后只用到了一部分数据,剩余的排好序的数据被抛弃,效率低。
思路二:
1.另建一个新的长度为3的数组,用来保存最大的三个不等的数。
2.以nums数组第一个元素为最大值,使用简单选择排序算法。选出最大的不同的三个数放入新数组。选够3个即可方法返回,否则返回最大值。
class Solution {
public int thirdMax(int[] nums) {
int[] maxThreeNum = new int[3];
int certainNumSum = 0;
int maxNumIndex;
for(int i=0; i<nums.length; i++)
{
int temp;
maxNumIndex=i;
for(int j=i+1; j<nums.length; j++)
{
if(nums[j] > nums[maxNumIndex])
{
maxNumIndex=j;
}
}
temp = nums[i];
nums[i] = nums[maxNumIndex];
nums[maxNumIndex] = temp;
if(certainNumSum==0 || nums[i]!=maxThreeNum[certainNumSum-1])
maxThreeNum[certainNumSum++]=nums[i];
if(certainNumSum==3)
return maxThreeNum[2];
}
return maxThreeNum[0];
}
}
问题:时间耗时减少,但时间复杂度为O(n2),效率较低。
思路三:
1.另建一个新的长度为3的数组,用来保存最大的三个不等的数。
2.遍历数组,每次得到的一个元素都要和新数组的三个元素进行比较。相当于对这四个数进行排序,最小值被覆盖。遍历一遍就能得到最大的三个数。
class Solution {
public int thirdMax(int[] nums) {
long[] maxThreeNum = {Long.MIN_VALUE, Long.MIN_VALUE, Long.MIN_VALUE};
for(int i=0; i<nums.length; i++)
{
if(nums[i] > maxThreeNum[0])
{
maxThreeNum[2] = maxThreeNum[1];
maxThreeNum[1] = maxThreeNum[0];
maxThreeNum[0] = nums[i];
}
else if(nums[i] < maxThreeNum[0] && nums[i] > maxThreeNum[1])
{
maxThreeNum[2] = maxThreeNum[1];
maxThreeNum[1] = nums[i];
}
else if(nums[i] < maxThreeNum[1] && nums[i] > maxThreeNum[2])
{
maxThreeNum[2] = nums[i];
}
}
if(maxThreeNum[2] == Long.MIN_VALUE)
return (int)maxThreeNum[0];
else
return (int)maxThreeNum[2];
}
}
注意:
1.数组元素初始化值不能为Interger.MIN_VALUE,因为nums数组元素可取此值,最好初始化为Long.MIN_VALUE,最终返回时还要转为int
改进:
仍不是最优解,最后发现将数组拆开,写成3个长整型就行了。
class Solution {
public int thirdMax(int[] nums) {
long max = Long.MIN_VALUE;
long min = Long.MIN_VALUE;
long second = Long.MIN_VALUE;
for(int i=0; i<nums.length; i++)
{
if(nums[i] > max)
{
min = second;
second = max;
max = nums[i];
}
else if(nums[i]<max && nums[i]>second)
{
min = second;
second = nums[i];
}
else if(nums[i]<second && nums[i]>min)
{
min = nums[i];
}
}
if(min == Long.MIN_VALUE)
return (int)max;
else
return (int)min;
}
}