Leetcode 128 最长连续序列

本文介绍了如何利用哈希集和优化策略在LeetCode题目中找到一个整数数组中的最大连续递增子序列,避免了暴力枚举中的重复计算,以O(n)的时间复杂度求解。作者通过举例和反证法证明了这种方法的有效性。

题目信息

LeetCode地址: . - 力扣(LeetCode)

题目理解

题目要求O(n)的时间复杂度,也就不能使用排序或者暴力枚举的方法解题。

暴力枚举的缺陷在于重复计算。

我们通过以下数列来说明存在哪些重复计算:

 4,3,2,1。

第一个数是4, 4+1=5, 5不存在,累加结束;最大连续长度是1

第二个数是3,3+1=4,4存在;4+1=5, 5不存在,累加结束;最大连续长度是2

第三个数是2, 2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是3

第四个数是1,1+1=2,2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是4

可以看到,每一个更小的数载计算连续长度时,都重复进行了比他大一个数的计算过程。

为了尽可能的延后这个计算,我们可以:如果当前数的减1的数存在,则先跳过这个数,否则进行累加计算。

第一个数是4, 4-1=3, 3存在,跳过这个数。

第二个数是3,3-1=2,2存在;跳过这个数。

第三个数是2, 2-1=1, 1存在;跳过这个数。

第四个数是1,1-1=0 0不存在,开始计算累加长度:1+1=2,2+1=3,3+1=4,4+1=5, 5不存在,累加结束;最大连续长度是4

可以看到,这样调整后的计算过程没有任何一步重复。

同时,我们也可以通过反证法轻而易举的证明该方法一定能够得到最大长度。

先假设我们得到的结果是largest, 而存在一种更长的数列betterArray={m1, m2, m3... mn}能够做到mn-m1+1= bigger, 而bigger > largest.

而通过我们的方法,一定能够捕捉并跳过m2,m3...到mn, 而从m1开始计算长度,故 一定能满足

largest >= (mn-m1+1). 所以假设一定不成立,故证明我们的方法一定能得到最优解。 

写法1

public int longestConsecutive(int[] nums) {
        int max = 0;
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }
        for (int num: nums) {
            if (!set.contains(num-1)) {
                int current = 1;
                while (set.contains(++num)) {
                    current++;
                }
                max = Math.max(max, current);
            }
        }
        return max; 
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值