题目描述
给定一个未排序的整数数组,找出最长连续序列的长度。
要求算法的时间复杂度为 O(n)。
示例:
输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
方法一:哈希表
class Solution {
public int longestConsecutive(int[] nums) {
Map<Integer,Integer> map=new HashMap<>();
int len=0;
//存入哈希表
for(int i:nums){
map.put(i,0);
}
//依次访问
for(int i:nums){
int index=1;
int count=1;
//两个哨兵,判断是否要增加索引
boolean flag1=true,flag2=true;
while(map.get(i)==0){
if(flag1&&map.containsKey(i+index)){
count++;
map.put(i+index,1);
}
if(flag2&&map.containsKey(i-index)){
count++;
map.put(i-index,1);
}
//若没有连续递增,flag1置flase
if(!map.containsKey(i+index)){
flag1=false;
}
//若没有连续递减,flag2置flase
if(!map.containsKey(i-index)){
flag2=false;
}
if(!flag1&&!flag2){
break;
}
index++;
}
map.put(i,1);
//贪心计算长度
len=Math.max(len,count);
}
return len;
}
}
优化
- 哨兵改过就不用再改了
if(flag1&&!map.containsKey(i+index)){
flag1=false;
}
if(flag2&&!map.containsKey(i-index)){
flag2=false;
}
再优化
- 上面方法采用用哈希表是否为0避免重复计算,但事实上上面的方法都对其进行了两边的判断,不免会增加复杂度
- 可以用set 当遇到子序列的起点时,再开始计算长度
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> set=new HashSet<>();
for(int i:nums){
set.add(i);
}
int len=0;
for(int i:nums){
if(!set.contains(i-1)){
int count=1;
int index=1;
while(set.contains(i+index)){
count++;
index++;
}
len=Math.max(len,count);
}
}
return len;
}
}