题目描述:
给定一个未排序的整数数组 nums
,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
进阶:你可以设计并实现时间复杂度为 O(n) 的解决方案吗?
示例 1:
1 | 输入:nums = [100,4,200,1,3,2] |
示例 2:
1 | 输入:nums = [0,3,7,2,5,8,4,6,0,1] |
提示:
- $0 <= nums.length <= 10^4$
- $-10^9 <= nums[i] <= 10^9$
链接:
https://leetcode-cn.com/problems/longest-consecutive-sequence
题目分析
1.Set
阅读示例后发现,题目所说的连续序列只需要数字的值连续,而不需要在数组中相对有序,更不需要连续出现,则某个数在数组中只有 “存在” 与 “不存在” 两种状态,它的个数、位置都是没有影响的,我们可以考虑使用一个 set
容器来存放这些数,这样在存放的时候就可以同时进行排序。
存放所有的数后,我们只需要对 set
进行一次遍历,每次寻找数字的值是否连续,并维护一个 count
进行计数,一旦不连续则重置,寻找下一个连续序列,与此同时记录最大的序列长度即可。代码中的 result
用于存放最大序列长度(也即结果),count
用于序列长度计数,pre
用于存放遍历的上一个值(用于比较)。重置的时候是重置为 1
(也即已经算上当前的这个数)。
1 | class Solution { |
时间复杂度:$O(n\log n)$,其中 $n$ 为数组的大小。我们遍历了一次数组存入 set
容器中,每一个数的存入需要 $O(\log n)$,再遍历一次 set
找到答案。
时间复杂度:$O(n)$,其中 $n$ 为数组的大小。我们需要一个 set
容器来存放数组中出现的所有数字,最大的大小为 $n$。
PS:进阶要求的时间复杂度是 $O(n)$,但是我看了官方题解仍然觉得是 $O(n\log n)$,并没有更好的算法了吧。看了官方题解的评论,大概是说最优情况下是 $O(n)$,那倒确实。
PPS:所以好像直接对原数组排序一遍再遍历更省事更快,还不需要那么多的额外空间…
PPPS:发生了非常魔幻的事情,8月4日的这一天重新看这道题,发现官方题解和我之前看的不一样了,但是又是发布于2020年的题解,就好像做梦一样。这道题确实是存在 $O(n)$ 的解法的。
2.哈希表
如果我们使用哈希表来存储这些数字,然后再遍历哈希表进行查找,每次查找的时候,如果这个数是连续序列的第一个数(也即其减一不存在于哈希表中),我们就查找这个连续序列的长度。而查找哈希表中是否存在某个数的复杂度是 $O(1)$,则我们遍历的时间复杂度为 $O(n)$。如此遍历完哈希表就可以获得所有的连续序列长度了。当然,我们只需要记录下最长的那个长度。
1 | class Solution { |
时间复杂度:$O(n)$,其中 $n$ 为数组的大小。我们遍历了一次数组存入哈希表中,所需时间复杂度为 $O(n)$。然后哈希表中的每个数字被遍历两次,一次为外层遍历时,一次是作为连续序列中的一个数被遍历一次(每个连续序列只会在第一个数进入内循环时被遍历,有且仅有一次),因此时间复杂度也是 $O(n)$。
时间复杂度:$O(n)$,其中 $n$ 为数组的大小。我们需要一个哈希表来存放数组中出现的所有数字,最大的大小为 $n$。