哈希表题目:最长连续序列

题目

标题和出处

标题:最长连续序列

出处:128. 最长连续序列

难度

6 级

题目描述

要求

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

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

示例

示例 1:

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

示例 2:

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

数据范围

  • 0 ≤ nums.length ≤ 10 5 \texttt{0} \le \texttt{nums.length} \le \texttt{10}^\texttt{5} 0nums.length105
  • -10 9 ≤ nums[i] ≤ 10 9 \texttt{-10}^\texttt{9} \le \texttt{nums[i]} \le \texttt{10}^\texttt{9} -109nums[i]109

解法

思路和算法

为了寻找最长连续序列,对于数组 nums \textit{nums} nums 中的元素 num \textit{num} num,需要找到最大的正整数 k k k,使得从 num \textit{num} num num + k − 1 \textit{num} + k - 1 num+k1 都在数组中,则从 num \textit{num} num 开始的最长连续序列的长度是 k k k

为了判断一个元素是否在数组中,可以使用哈希集合存储数组中的元素,判断一个元素是否在哈希集合中的时间复杂度是 O ( 1 ) O(1) O(1)。假设数组 nums \textit{nums} nums 的长度是 n n n,如果对数组中的每个元素都进行上述操作,则对于一个元素计算从该元素开始的最长连续序列的长度需要 O ( n ) O(n) O(n) 的时间,总时间复杂度是 O ( n 2 ) O(n^2) O(n2)

为了将时间复杂度降低到 O ( n ) O(n) O(n),必须进一步优化。对于数组 nums \textit{nums} nums 中的元素 num \textit{num} num,如果 num − 1 \textit{num} - 1 num1 也在数组中,则将 num − 1 \textit{num} - 1 num1 添加到 num \textit{num} num 的前面可以使得连续序列的长度加 1 1 1,因此从 num − 1 \textit{num} - 1 num1 开始的最长连续序列的长度一定大于从 num \textit{num} num 开始的最长连续序列的长度。基于该结论,对于数组 nums \textit{nums} nums 中的元素 num \textit{num} num,只有当 num − 1 \textit{num} - 1 num1 不在数组中时,才需要计算从 num \textit{num} num 开始的最长连续序列的长度。

将数组 nums \textit{nums} nums 中的元素都加入哈希集合之后,遍历哈希集合,对于每个元素 num \textit{num} num,如果 num − 1 \textit{num} - 1 num1 在哈希集合中则跳过 num \textit{num} num,如果 num − 1 \textit{num} - 1 num1 不在哈希集合中则计算从 num \textit{num} num 开始的最长连续序列的长度,具体做法如下:

  1. maxNum \textit{maxNum} maxNum 表示从 num \textit{num} num 开始的最长连续序列的最大元素,初始时 maxNum = num \textit{maxNum} = \textit{num} maxNum=num,如果 maxNum + 1 \textit{maxNum} + 1 maxNum+1 在哈希集合中则将 maxNum \textit{maxNum} maxNum 的值加 1 1 1,重复增加 maxNum \textit{maxNum} maxNum 的值,直到 maxNum + 1 \textit{maxNum} + 1 maxNum+1 不在哈希集合中;

  2. num \textit{num} num 开始的最长连续序列的长度是 maxNum − num + 1 \textit{maxNum} - \textit{num} + 1 maxNumnum+1,用该长度更新整个数组的最长连续序列的长度。

遍历结束之后,即可得到整个数组的最长连续序列的长度。

优化后的做法中,由于不可能作为最长连续序列的第一个数的元素会跳过,因此哈希集合中的每个元素只会被遍历一次,时间复杂度是 O ( n ) O(n) O(n)

代码

class Solution {
    public int longestConsecutive(int[] nums) {
        Set<Integer> set = new HashSet<Integer>();
        for (int num : nums) {
            set.add(num);
        }
        int maxLength = 0;
        for (int num : set) {
            if (set.contains(num - 1)) {
                continue;
            }
            int maxNum = num;
            while (set.contains(maxNum + 1)) {
                maxNum++;
            }
            maxLength = Math.max(maxLength, maxNum - num + 1);
        }
        return maxLength;
    }
}

复杂度分析

  • 时间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。遍历数组 nums \textit{nums} nums 并将全部元素加入哈希集合需要 O ( n ) O(n) O(n) 的时间,遍历哈希集合计算最长连续序列的长度时,由于不可能作为最长连续序列的第一个数的元素会跳过,因此哈希集合中的每个元素只会被遍历一次,时间复杂度是 O ( n ) O(n) O(n)

  • 空间复杂度: O ( n ) O(n) O(n),其中 n n n 是数组 nums \textit{nums} nums 的长度。需要使用哈希集合存储数组 nums \textit{nums} nums 中的元素,哈希集合中的元素个数不会超过 n n n

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

伟大的车尔尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值