哈希表+双指针
思路
- 先排序,后遍历
- 题目要求找出最长连续序列的长度,注意是找出,所以数组中的元素有可能是重复的。
- 如何排除重复值,很容易就想到
Set
集合,所以转成Set
集合 - 后续的遍历用到双指针,为了便于操作又把Set集合转数组,再排序。
- 因为用到
Arrays.sort()
,其时间复杂度 为O(nlogn),其实是不符合所要求的O(n),但偷懒更快乐。
代码
/**
* 5~7ms
*
* 若Set的实现类改成LinkedHashSet(保证插入顺序 和遍历取出顺序一致) 7ms
*/
public static int longestConsecutive(int[] nums) {
int ans = 0;
if (nums == null || nums.length == 0) return ans;
if (nums.length == 1) return 1;
Set<Integer> set=new HashSet<>();
for(int num:nums){
set.add(num);
}
int[] nums2=new int[set.size()];
int count=0;
for(int num:set){
nums2[count++]=num;
}
if(nums2.length==1) return 1;
Arrays.sort(nums2);
int len = nums2.length, start = 0, end = 1;
while (end < len) {
if (start == end) {
ans = Math.max(ans, 1);
} else {
if(nums2[end]-nums2[end-1]!=1){
ans = Math.max(ans, end - start);
start = end;
ans = Math.max(ans, 1);
}else{
ans=Math.max(ans, end-start+1);
}
}
end++;
}
return ans;
}
优化
- 由上面臃肿的代码可以发现空间开销还是有点大的
- 对于重复值,可以不用
Set
加工,只需在对排序后的数组遍历时,用continue
跳过即可。
代码
//2ms
public static int longestConsecutive2(int[] nums){
int max=0;
if(nums==null||nums.length==0) return max;
Arrays.sort(nums); //O(nlogn)
int curLen=1;max=1;
for(int i=1,len=nums.length;i<len;i++){ //O(n)
if(nums[i]-nums[i-1]==1){
curLen++;
}else if(nums[i]==nums[i-1]){ //重复值跳过
continue;
}else{
max=Math.max(max,curLen);
curLen=1;
}
}
return Math.max(max, curLen);
}