刷题笔记 剑指 Offer II 119. 最长连续序列

剑指 Offer II 119. 最长连续序列
难度: 中等

最容易想到的思路就是先排序,排序后遍历数组中的元素,看看nums[i] == nums[i - 1] + 1的条件是否成立,如果成立,说明符合数据递增。
然而,在遍历过程中还会遇到一种情况。例如,对[0, 2, 1, 1]先进行排序处理,得到的答案是[0, 1, 1, 2],按照遍历的思路,发现最大值不是3,而是2,因为在下标为2的索引时,nums[2]不满足nums[2] == nums[1] + 1的条件
因此,最好对数组做一遍过滤,每个数据只留下一个。显然,这里要用到哈希表set。在这里,我们希望数据在放入哈希表后仍然有序,因此应该使用TreeSet
class Solution {
    public int longestConsecutive(int[] nums) {
        // 通过TreeSet在排序数组的同时,过滤数组,使其没有重复数
        TreeSet<Integer> set = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1 - o2;
            }
        });
        for (int i = 0; i < nums.length; i++) {
            set.add(nums[i]);
        }
        Iterator<Integer> iterator = set.iterator();
        // 去除nums中不包含任何元素的情况
        if (!iterator.hasNext()) return 0;
        int count = 1, max = 1;
        int pre = iterator.next();
        while (iterator.hasNext()) {
            int curr = iterator.next();
            // 若满足前一个元素+1等于当前元素,则符合条件,count++,否则,不满足序列条件,重置count
            if (curr == pre + 1) {
                count++;
            } else {
                count = 1;
            }
            pre = curr;
            max = Math.max(max, count);
        }
        return max;
    }
}
本题中使用TreeSet,耗费的时间较长,可以使用其它方法降低时间。可以看到,耗时较长的步骤主要在于排序与去重两个方面。那么控制时间,就要从这两方面入手
根据题意,分析可知,如果不使用TreeSet自动排序并去重的话,排序步骤是必须的,只有这样才能看出数组的递增关系,进而找到序列
因此,就要在去重的步骤上下手,本题是否能做到不去重?
这里提供只遍历一次得到结果的代码,只需要在相等时的条件判断中加入一个跳过的选项即可
class Solution {
    public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        Arrays.sort(nums);
        int count = 1, max = 1;
        for (int i = 1; i < nums.length; i++) {
            if (nums[i] == nums[i - 1] + 1) {
                count++;
                max = Math.max(max, count);
            } else if (nums[i] == nums[i - 1]) {
                // 当前一个数与当前数相等时,只需要跳过即可
                continue;
            } else {
                count = 1;
            }
        }
        return max;
    }
}
通过这种方式,代码的运行速度是之前的3倍,运行速度显著提高
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值