原题:

Longest Consecutive Sequence - LeetCode

Description:

Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.

You must write an algorithm that runs in O(n) time.

Example 1:

Input: nums = [100,4,200,1,3,2]Output: 4Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

Example 2:

Input: nums = [0,3,7,2,5,8,4,6,0,1]Output: 9

Constraints:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109
思路:

\1. 首先想到的是排序,然后判断相邻两数是否差值为 1, 计算满足此条件的最长子序列长度。

但复杂度是 T:O(nlogn), 空间复杂度 S:O(1)

题目既然要求使用 O(n) 复杂度来解决问题,那么第一反应是通过外部数据结构来加快搜索,以空间换时间。

\2. 对于一个数 k,在判断它是否属于一个连续子序列时,如果采用原始搜索,只能遍历 n 去查找 k + 1 或 k - 1 是否存在于原数组。

如果我们先将原数组存在 set 里,再判断 k + 1 和 k - 1 是否存在,这样复杂度不是降到 O(1) 了?

然后为了避免每一个数都要双向查找(这样复杂度会接近 O(n^2)),我们需要选择一边进行跳过,即 如果 k - 1 已存在于 set 中,那么直接跳过(因为当 k = k - 1 时也会搜索一次,这次不搜索也没事)。

完整代码:
// AC: Runtime: 275 ms, faster than 20.28% of Java online submissions for Longest Consecutive Sequence.
// Memory Usage: 54.4 MB, less than 42.86% of Java online submissions for Longest Consecutive Sequence.
// .
// T:O(n), S:O(n)
// 
class Solution {
    public int longestConsecutive(int[] nums) {
        if (nums.length == 0) {
            return 0;
        }
        int max = 1;
        HashSet<Integer> record = new HashSet<>();
        for (int i: nums) {
            record.add(i);
        }

        for (int i: nums) {
            if (!record.contains(i - 1)) {
                int j = i + 1;
                while (record.contains(j)) {
                    j++;
                    max = Math.max(max, j - i);
                }
            }
        }

        return max;
    }
}