题目
给定无序数组,返回其中最长的连续序列的长度(要求值连续,位置可以不连续)。
例如
**3,4,5,6**为连续的自然数
要求:空间复杂度 ,时间复杂度
解题思路:排序
因为数组是无序的,如果要想找出最长的连续序列(这里序列的顺序可以打乱),我们最容易想到的就是先对数组进行排序,然后再查找。
![[NC]95. 数组中的最长连续子序列 - 图4](/uploads/projects/mylearn@leetcode/cf0135c1b52b3d165daea26aa84fe2aa.png)
复杂度分析
时间复杂度: ,该方法需要遍历一次数组所有元素,但是需要一次排序数组 。
空间复杂度: ,该方法使用常数空间 。
我的代码
public class Solution {public int MLS(int[] arr) {if (arr == null || arr.length == 0)return 0;int longest = 1;//记录最长的有序序列int count = 1;//目前有序序列的长度//先对数组进行排序Arrays.sort(arr);for (int i = 1; i < arr.length; i++) {//跳过重复的if (arr[i] == arr[i - 1])continue;//比前一个大1,可以构成连续的序列,count++if ((arr[i] - arr[i - 1]) == 1) {count++;} else {//没有比前一个大1,不可能构成连续的,//count重置为1count = 1;}//记录最长的序列长度longest = Math.max(longest, count);}return longest;}}
解题思路:哈希表
一个数字连续序列是不包含重复的数字的,所以使用 去重。
![[NC]95. 数组中的最长连续子序列 - 图8](/uploads/projects/mylearn@leetcode/3c118ab757e8923dd9ad4c11dd100cb6.png)
为了保证的时间复杂度,避免重复枚举一段序列,我们要从序列的起始数字向后枚举。也就是说如果有一个
的连续序列,我们只会以
为起点向后枚举,而不会从
向后枚举。
![[NC]95. 数组中的最长连续子序列 - 图13](/uploads/projects/mylearn@leetcode/d6c9f91aef1203e00c8279e91cb3810e.png)
如何保证只会以为起点向后枚举?
其实只需要每次在哈希表中检查是否存在即可。如果
存在,说明当前数
不是连续序列的起始数字,我们跳过这个数。
复杂度分析
时间复杂度: ,其中
为数组的长度,该方法需要遍历一次数组所有元素 。
空间复杂度: ,哈希表存储数组中所有的数需要
的空间。
我的代码
class Solution {public static int longestConsecutive(int[] nums) {if (nums == null || nums.length == 0) return 0;HashSet<Integer> set = new HashSet<>();// HashSet 去重for (int i = 0; i < nums.length; i++) {set.add(nums[i]);}int res=0;for (int num : set) {int count = 0;if (set.contains(num - 1)) continue;else{// 统计起始序列长度while(set.contains(num++)) count++;res= Math.max(count,res);}}return res;}}
