力扣414题:第三大的数

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

输入:[3, 2, 1]
输出:1
解释:第三大的数是 1 。

这个题力扣给的难度是简单。

一拿到题第一个想到的就是排序,不过很显然用排序的话效率会很低,题目建议将时间复杂度优化到O(n),不过还是先把题目写出来再去优化吧。

错误的算法思路:先判断这个数组有多长,如果小于3就另作判断,大于3就将其按递增排序后选择倒数第三个数字即为答案。

然而我又被锤了
这次是没读清楚题目的意思,题目要求返回的是第三大的数字,这个数组中是有可能有重复的数字的,所以直接返回倒数第三个数字是不靠谱的,而且就算数组长度大于3,也不一定是有第三大的数字的,所以上面的算法思路是有问题的,题目要求样例中也给出了这种情况,看来看题还是得仔细一点。

新的算法思路:先将数组进行排序,然后通过一个循环从数组最大的数开始遍历整个数组,设置一个标记变量,如果说当前数字和前一个数字不一样,标记变量就加1,如果一样就继续遍历,直到遍历完整个数组,如果标记变量仍然没有达到2,则说明该数组中没有第三大的数字,则直接返回数组最后一个元素(最大的元素)

源码部分:时间复杂度为O(nlgn)因为用到了快排,空间复杂度为O(1);

import static java.util.Arrays.sort;
class Solution {
    public int thirdMax(int[] nums) {
        int i;
        int flag = 0;
        sort(nums);
        for (i = nums.length - 1; flag != 2; i--) {
            //这里不是当i<0时,因为下面有i-1的下标,所以要设置为当i==0时退出
            if(i == 0){
                return nums[nums.length - 1];
            }else{
                if (nums[i] != nums[i - 1]) {
                    flag++;
                }
            }
        }
        return nums[i];
    }
}

执行用时:
2 ms ,在所有 Java 提交中击败了46.66%的用户
内存消耗:
38.3 MB, 在所有 Java 提交中击败了52.80%的用户

在题解区看到有大佬有红黑树来写,咋自己就想不到呢,java中的这个题可以用TreeSet来实现呢。

思路一: 借用TreeSet(红黑树) O(n)
比较好想的思路
维护一个只有3个元素的TreeSet,如果大于三个元素就就把Set中的最小最小值remove掉。
最后如果Set中元素小于3就返回Set最大值,否则返回最小值。
时间复杂度: O(n * log3) == O(n)
作者:happy_yuxuan

思路二: 用三个变量来存放第一大,第二大,第三大的元素的变量,分别为one, two, three;
遍历数组,若该元素比one大则往后顺移一个元素,比two大则往往后顺移一个元素,比three大则赋值个three;
最后得到第三大的元素,若没有则返回第一大的元素。
作者:happy_yuxuan


待我将java集合复习完后再来更新这个TreeSet的算法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值