力扣HOT100-3 最长连续序列(Java实现)

题目

题目解读

1.给定一个未排序的整数数组 nums,找出其中数字连续的最长序列的长度。

2.注意序列中的元素在原数组中不必连续,只需要数值连续

开始解题

一、排序法

思路:

如果数组是排好序的,那么"连续"就变成了 nums[i] - nums[i-1] == 1

只需一次遍历,维护当前连续长度 curLen 和全局最大长度 maxLen

重复元素:排序后相邻元素差值为 0 时,直接跳过,不应影响计数。

断裂处理:差值 > 1 时,更新 maxLen 并重置 curLen

边界情况:空数组返回 0,单元素数组返回 1;循环结束后还需要再更新一次 maxLen

核心流程:

1.如果数组长度为 0,直接返回 0。

2.对原数组进行原地排序(Arrays.sort(nums))。

3.初始化当前长度 curLen = 1,最大长度 maxLen = 1。

4.从 i = 1 开始遍历数组:

如果 numsi - numsi-1 == 1:curLen++。

如果差值 > 1:用 curLen 更新 maxLen,然后重置 curLen = 1。

如果差值 == 0:忽略(重复元素)。

6.遍历结束后,用最后一次的 curLen 更新 maxLen(防止最长序列在末尾)。

5.返回 maxLen。

代码

java 复制代码
public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        Arrays.sort(nums);
        int maxLen = 1;
        int curLen = 1;
        for (int i = 1; i < nums.length; i++) {
            int diff = nums[i] - nums[i - 1];
            if (diff == 1) {
                curLen++;
            } else if (diff > 1) {
                maxLen = Math.max(maxLen, curLen);
                curLen = 1;
            }
            // diff == 0 时什么也不做
        }
        return Math.max(maxLen, curLen);
    }

二、哈希集合法(HashSet)

思路:

如果对每个数都去检查 x+1, x+2, ...,会产生大量重复遍历,最坏会退化为 O(n²)。

为此,我们只从序列的起点 开始向后数。一个数 x 是起点的条件是:x-1 不在集合中。

这样,每个数字只会被作为序列的一部分访问一次,总复杂度均摊为 O(n)。

核心流程:

1.将所有数字放入 HashSet<Integer>。

2.初始化 maxLen = 0。

3.遍历集合中的每个数字 num:

如果 num - 1 不在集合中,说明 num 是一个连续序列的起点。

从 num 出发,定义 curNum = num,curLen = 1。

当 curNum + 1 在集合中时,curNum++,curLen++。

用 curLen 更新 maxLen = max(maxLen, curLen)。

4.返回 maxLen。

代码

java 复制代码
public int longestConsecutive(int[] nums) {
        if (nums.length == 0) return 0;
        // 将所有数存入哈希集合
        Set<Integer> set = new HashSet<>();
        for (int num : nums) {
            set.add(num);
        }
        int maxLen = 0;
        for (int num : set) {
            // 只有当 num 是序列起点时才处理
            if (!set.contains(num - 1)) {
                int curNum = num;
                int curLen = 1;
                while (set.contains(curNum + 1)) {
                    curNum++;
                    curLen++;
                }
                maxLen = Math.max(maxLen, curLen);
            }
        }
        return maxLen;
    }

感谢您能够看到这里,一起见证小何同学的算法学习,如果您有不同的见解,希望能得到您的指点和点悟;如果您是和我一样的同学,也希望这篇文章能对您有所帮助。