【哈希】【中等】最长连续序列

题目

给定一个未排序的整数数组 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 <= numsi <= 109

解法1:排序后暴力

  • 对于int 数组,利用sort方法进行升序排序,以 下面的代码为例,排序后为1 , 1 , 2 , 2 , 3 , 4 , 100 , 200
  • 设定当前数组位置从 i = 0 开始,比较 numsi 和 numsi+1 的关系
    • 如果 numsi +1 == numsi+1,当前长度加一;
    • 如果 numsi == numsi+1,则进行跳过;
    • 如果都不满足,则设定当长度 cur = 0 ,比较当前值cur和最大值longest,更大的作为新的longest;
  • 返回最后一个连续子串长度 cur 和 之前最大字串长度的最大值
java 复制代码
public class Longest_consecutive_sequence {
    public static int longestConsecutive(int[] nums) {
        if (nums == null || nums.length == 0)
            return 0;//为0的考虑,也可想步骤2一样初始设置为0,最后返回为0
        Arrays.sort(nums);//先给这个数组进行排序
        int longest = 1;//待比较的最大串
        int current = 1;//当前最长长度
        for (int i = 0; i < nums.length-1; i++) {
            if (nums[i] + 1 == nums[i+1]) {
                current++;
            }
            else if (nums[i] == nums[i+1]) {
                continue;
            }
            else{
                longest = Math.max(longest, current);
                current = 1;
            }

        }
        return Math.max(longest, current);//当前最长和最后的cur进行比较
    }

    public static void main(String[] args) {
        int[] x = new int[]{100, 4, 200, 1, 3, 1, 2, 2};
        System.out.println(longestConsecutive(x));
    }
}

解法2:Set存储后依次查找

  • 遍历每一个数组中的每一个元素,将其存放在HashSet结构中(Set中的元素不重复)
  • 遍历Set中的每一个元素(注意这里是遍历Set不是遍历原数组,原数组中可能存在多个重复值,复杂度变高)
  • 对于Set中的每一个元素,若没有比当前元素更小一个的值,即 i-1,则证明该元素是子序列中最小值,此时开始依次循环记录连续序列的长度,直到不连续,则在之前最长长度 max 和当前长度 current 中选取最大值即可
java 复制代码
public class Longest_consecutive_sequence {
    public static int longestConsecutive(int[] nums) {
        Set<Integer> set  = new HashSet<>();
        for (int num : nums) set.add(num);
        int max = 0;
        for (int i: set) {
            if(!set.contains(i-1)) {
                int temp = i + 1;
                int current = 1;
                while (set.contains(temp)) {
                    current++;
                    temp++;
                }
                max = Math.max(max, current);
            }
        }
        return max;
    }
}