【LC100】No128. 最长连续序列

题目描述

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

提示:

  • 0 <= nums.length <= 105

  • -109 <= nums[i] <= 109

示例

示例 1:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。

示例 2:

输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

示例 3:

输入:nums = [1,0,1,2]
输出:3

链接

https://leetcode.cn/problems/longest-consecutive-sequence/description/?envType=study-plan-v2&envId=top-100-liked

思路

沾沾自喜地做完之后,发现题目要求用 O(n) 的复杂度解决问题,自闭了。

看到题目中“只需要返回长度,且不要求序列元素在原数组中连续”,我们可以非常容易地想到排序后再处理。但题目要求 O(n) 时间复杂度,排序会变成 O(nlogn),所以不能用排序。

设数组下标为 i,我们需要分别找到以 nums[i] 开头的最长连续序列,最后返回最大的长度。

也即,根据 nums[i],依次寻找 nums[i]+1、nums[i]+2...是否存在在数组中

看示例可知,相等元素不计入长度计算,所以还需要去重;同时还需要快速查找某元素是否存在于数组中

综合上述两点,可以想到将数组转化为 set

本题解法中有个非常巧妙的思路:剪枝,省去操作一些“已经从开头就知道这个不是最优解”的情况。

对于 nums[i],如果 nums[i]-1 在 set 中,那么没必要继续找 nums[i] 开头的序列,以 nums[i]-1 开头的序列一定比这个长

解法:哈希set+剪枝

代码

class Solution {
    public int longestConsecutive(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        // 转化为set:去重+方便拿取
        Set<Integer> numSet = new HashSet<>(); 
        for (int num : nums) {
            numSet.add(num);
        }
        int maxRes = 1;
        for (int num : numSet) {
            // 剪枝
            if (numSet.contains(num - 1)) {
                continue;
            }
            int maxTemp = 1;
            int numTemp = num;
            while (numSet.contains(++numTemp)){
                maxTemp++;
            }
            maxRes = Math.max(maxRes, maxTemp);
        }
        return maxRes;
    }
}
  • 时间复杂度:O(n)

  • 空间复杂度:O(n)


【LC100】No128. 最长连续序列
https://tiamo495.com//archives/lc100-no128.-zui-chang-lian-xu-xu-lie
作者
tiamo495
发布于
2025年07月16日
许可协议