128. 最长连续序列
题目描述:
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
思路:HashSet
先把所有元素存入一个hashset,方便判断某个元素是否存在,此题解题思路为先找到某个连续序列的最小元素,然后从该元素开始不断判断下个元素是否存在,如果存在则该连续序列的长度加一,否则结束计数。
而找到某个连续序列的最小元素的方式,就是遍历hashset,
如果当前元素减一存在于set中,进入下轮循环,因为我们需要找到最长连续序列中的最小的元素,当前元素显然不是最小的;
如果当前元素减一不存在与set中,说明当前元素是包含当前元素的最长连续序列中的最小元素,从它开始遍历存,不断判断下个元素是否存在,如果存在则序列长度加一,直至跳出本次最长连续序列的长度计数
1 class Solution {
2 public int longestConsecutive(int[] nums) {
3 // 先把所有元素都存入一个hashSet
4 HashSet<Integer> set = new HashSet<>();
5 for(int i = 0; i < nums.length; i++){
6 set.add(nums[i]);
7 }
8 int maxLength = 0;
9 // 遍历hashset,
10 for(Integer num : set){
11 // 如果当前元素减一存在于set中,进入下轮循环,
12 // 因为我们需要找到最长连续序列中的最小的元素,当前元素显然不是最小的
13 if(set.contains(num - 1)){
14 continue;
15 }else{
16 // 如果当前元素减一不存在与set中,说明当前元素是包含当前元素的最长连续序列中的最小元素,
17 // 从它开始遍历存,不断判断下个元素是否存在
18 // 如果存在则序列长度加一,直至跳出本次最长连续序列的长度计数
19 int temp = num;
20 int count = 1;
21 while(set.contains(temp + 1)){
22 count++;
23 temp += 1;
24 }
25 maxLength = Math.max(maxLength, count);
26 }
27 }
28 return maxLength;
29 }
30 }
leetcode 执行用时:5 ms > 89.43%, 内存消耗:38.4 MB > 99.84%
复杂度分析:
时间复杂度:O(3n)。首先把数组存入set的复杂度为O(n)。 接下来的外层循环遍历了set的所有元素,对每个元素都判断了一次该元素减一是否存在于set中,所以时间花费也是O(n)。因为每个元素只会唯一的存在某一个连续序列,每个序列只会被遍历一次,所有序列长度之和刚好等于整个set的大小,所以内存层的while循环实际上是把所有元素都遍历了一遍,复杂度为O(n),。所以整体时间复杂度为O(3n).
空间复杂度:O(n)。需要一个set把所有元素都存下来,所以空间复杂度最大为O(n), 即当没有重复元素出现时,每个元素都必须存一遍。