力扣打卡 128-最长连续序列

Problem: 128. 最长连续序列

思路

这道题最直接的想法就是排序,排序之后连续的序列就很容易找到了。不过排序的时间复杂度是 O(NlogN),而题目要求我们时间复杂度为 O(N),这就得另想办法了。

想找连续序列,首先要找到这个连续序列的开头元素,然后递增,看看之后有多少个元素还在 nums 中,即可得到最长连续序列的长度了。

我们可以用空间换时间的思路,把数组元素放到哈希集合里面,然后去寻找连续序列的第一个元素,即可在 O(N) 时间找到答案。

解题方法

  1. 首先将给定的数组转化为一个哈希集合(HashSet),这样可以方便地进行快速元素的查找操作。
  2. 初始化一个变量 res 用于记录最长连续序列的长度,初始值为 0。
  3. 遍历集合中的每个元素 num
    1. 如果集合中存在 num - 1,说明 num 不是连续子序列的第一个元素,直接跳过。
    2. 如果集合中不存在 num - 1,说明 num 是连续子序列的第一个元素,开始向上计算连续子序列的长度。
      1. 初始化两个变量 curNum curLen,分别表示当前连续子序列的最后一个元素和当前连续子序列的长度,初始值分别为num和 1。
      2. 当集合中存在 curNum + 1 时,表示连续子序列还未结束,继续向上查找。
        1. curNum 增加 1,表示查找下一个连续元素。
        2. curLen 增加 1,表示连续子序列的长度增加 1。
      3. 更新最长连续序列的长度 res,取 rescurLen 中的较大值。
  4. 返回最终的最长连续序列长度 res

复杂度

  • 时间复杂度:
    O ( n ) O(n) O(n)
    其中 n 是数组 nums 的长度。遍历数组和哈希集合的操作都是线性时间复杂度的。

  • 空间复杂度:
    O ( n ) O(n) O(n)
    主要是由哈希集合所占用的空间所决定,最坏情况下需要存储整个数组。

Code

class Solution {
    public int longestConsecutive(int[] nums) {
        // 转化成哈希集合,方便快速查找是否存在某个元素
        HashSet<Integer> set = new HashSet<Integer>();
        for (int num : nums) {
            set.add(num);
        }

        int res = 0;

        for (int num : set) {
            if (set.contains(num - 1)) {
                // num 不是连续子序列的第一个,跳过
                continue;
            }
            // num 是连续子序列的第一个,开始向上计算连续子序列的长度
            int curNum = num;
            int curLen = 1;

            while (set.contains(curNum + 1)) {
                curNum += 1;
                curLen += 1;
            }
            // 更新最长连续序列的长度
            res = Math.max(res, curLen);
        }

        return res;
    }
}

你可能感兴趣的:(leetcode,哈希算法)