LeetCode HOT 100 —— 128.最长连续序列

题目

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
LeetCode HOT 100 —— 128.最长连续序列_第1张图片

思路

和最长递增子序列的区别是,本题不需要序列元素在原数组中连续,而最长递增子序列的递增要求在原数组中也要连续

这里考虑枚举的方法,对于数组的每个数x,考虑其为起点,不断尝试x + 1, x + 2...是否在数组中,如果最长匹配到了 x + y,那么以x为起点的最长连续序列即为x,x+1,x+2...x+y,长度为y+1,然后不断枚举即可

不过为了达到O(n)的 时间复杂度,需要进行优化:

  1. 判断x+1,x+2,x+3...是否在数组中,用哈希表查找,时间复杂度为O(1)
  2. 遍历数组中每个元素x。逐一遍历每个元素会产生很多重复工作,实际上无需一次针对每个元素x去判断x+1,x+2,x+3...是否在数组中。如果x-1已经在数组中的话,那么x-1肯定会进行相应的+1遍历,然后遍历到x,而且从x-1开始的+1遍历必定比从x开始的+1遍历得到的序列长度更长(因为必定多一个x-1x 这个长度)。因此,便可将在一个连续序列中的元素进行删减,让其只在最小的元素才开始+1遍历。比如,现有元素[1,2,4,3,5],当2,3,4,5发现均有比自己小1的元素存在,那么它们就不会开始+1遍历(即x发现有x-1存在,那么就不会从自己开始遍历),而1是连续序列中最小的元素,没有比自己小1的元素存在,所以会开始+1遍历。通过上述方式便可将时间复杂度优化至O(n)

java代码如下:

class Solution{
	public int longestConsecutive(int[] nums){
		//建立一个存储所有数的哈希表,同时起到去重功能
		Set<Integer> set = new HashSet<>();
		for(int x : nums){
			set.add(x);
		}
			
		int ans = 0;
		//遍历去重后的数字
		for(int x : set){
			int cur = x;//遍历到的当前数字,方便后续向后移动
			//只有当x-1不存在时,才开始向后遍历x+1,x+2,x+3...
			if(!set.contains(cur - 1)){
				while(set.contains(cur + 1)){//只要后面的元素存在,则后移继续遍历
					cur++;
				}	
			}		
			//经过循环得到的[x, cur]之间是连续的,数字有cur - x + 1个
			ans = Math.max(ans, cur - x + 1);
		}
		return ans;	
	}
}

你可能感兴趣的:(LeetCode,热题,HOT,100,leetcode,算法,数据结构)