wayne
wayne
发布于 2025-05-28 / 5 阅读
0
0

LeetCode - 最长连续序列 / 三数之和

最长连续序列

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

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

 

示例 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

 

提示:

  • 0 <= nums.length <= 105

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

解题思路

哈希去重

算法思路

这个解法的关键是利用哈希缓存避免重复遍历

  • 先用 HashSet 存储所有数字,利用其 O(1) 时间复杂度的查询特性;

  • 只从「连续序列的起点」(即某个数字 num 不存在 num-1 时)开始,向后逐个查找 num+1、num+2...,统计当前序列长度;

  • 全程维护最大长度,最终返回结果。

代码逻辑详解

class Solution {
    public int longestConsecutive(int[] nums) {
        // 步骤1:创建HashSet并存储所有数字,去重+快速查询
        Set<Integer> cache = new HashSet();
        for (int num : nums) {
            cache.add(num);
        }

        // 步骤2:初始化最长连续序列长度为0
        int maxLength = 0;
        
        // 步骤3:遍历集合中的每个数字(已去重)
        for (int num : cache) {
            // 核心判断:当前数字是否是「连续序列的起点」
            // 只有当num-1不存在时,才是起点,避免重复计算
            if (!cache.contains(num - 1)) {
                int temp = num + 1; // 从num的下一个数字开始查
                int tempMaxLength = 1; // 起点自身长度为1
                
                // 循环查找后续连续数字,统计当前序列长度
                while (cache.contains(temp)) {
                    tempMaxLength++; // 找到一个,长度+1
                    temp++; // 继续查下一个数字
                }
                
                // 更新全局最长长度
                maxLength = Math.max(maxLength, tempMaxLength);
            }
            // 如果num-1存在,说明num不是起点,直接跳过,避免重复遍历
        }

        // 步骤4:返回最长连续序列长度
        return maxLength;
    }
}

排序 + 动态规划

算法思路

这段代码采用排序 + 动态规划的思路:

  • 先把数组排序,让连续的数字挨在一起

  • 用一个 result 数组记录「以当前数字结尾的最长连续序列长度」

  • 遍历数组,根据当前数字和前一个数字的关系,更新 result 值,同时记录最大值

代码逻辑详解

class Solution {
    public int longestConsecutive(int[] nums) {
        // 步骤1:先对数组排序,让连续的数字相邻
        Arrays.sort(nums);
        // 步骤2:初始化最大值为0(处理空数组的情况)
        int max = 0;
        // 步骤3:创建result数组,长度和nums一致,每个元素初始值为1
        // 因为每个数字自身至少是一个长度为1的连续序列
        int[] result = new int[nums.length];
        Arrays.fill(result, 1);
        
        // 步骤4:遍历数组,逐个判断连续关系
        for (int i = 0; i < nums.length; i++) {
            // 处理第一个元素:没有前一个元素,直接更新max
            if (i == 0) {
                max = Math.max(max, result[i]);
                continue;
            }
            
            // 情况1:当前数字 = 前一个数字 + 1 → 连续,更新result[i]
            if (nums[i] == nums[i - 1] + 1) {
                result[i] = result[i - 1] + 1; // 继承前一个的长度并+1
                max = Math.max(max, result[i]); // 更新全局最大值
                continue;
            }
            
            // 情况2:当前数字 = 前一个数字 → 重复,长度和前一个一致
            if (nums[i] == nums[i - 1]){
                result[i] = result[i - 1];
                continue;
            }
            
            // 情况3:既不连续也不重复 → 保持初始值1,无需额外处理
        }
        // 步骤5:返回最长连续序列的长度
        return max;
    }
}


评论