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), 即当没有重复元素出现时,每个元素都必须存一遍。