题目:
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2]
,
The longest consecutive elements sequence is [1, 2, 3, 4]
. Return its length: 4
.
Your algorithm should run in O(n) complexity.
思路1:HashMap
维护一个HashMap<Integer,Integer> 存放每个数组及其两侧连续数字的长度。
读取每个数字num,判断num-1 num+1 是否在Map中,如果num-1 在,left为num-1在map中的value,如果num-1不在,则left=0;同理处理num+1。
则当前数字的所在连续数字的长度是:left+right+1,存入map,然后把该数字所在的连续数字两端的数字的长度也设置为left+right+1.
举个栗子:
100,1,200,4,2,3
[100=1]->
[100=1,1=1]->
[100=1,1=1,200=1]->
[100=1,1=1,200=1,4=1]-> num=2,1=1 ,3没有,所以2=(1+1) 1也赋值为2
[100=1,1=2,200=1,4=1,2=2]-> num=3 2=2,4=1 所以3=(2+1+1) 同时把1和4两个端点也赋值为4
[100=1,1=4,200=1,4=4,2=2,3=4]
最后得到最长长度为4
代码1:
public int longestConsecutive(int[] nums) {
if(nums.length==0||nums==null)
return 1;
int max =0;
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
for(int num:nums){
if(map.containsKey(num)){//如果map中有num,表示num是重复出现的,忽略
continue;
}else{
int left = (map.containsKey(num-1))?map.get(num-1):0;
int right= (map.containsKey(num+1))?map.get(num+1):0;
int cur_len = right+left+1;
map.put(num, cur_len);
map.put(num-left, cur_len);
map.put(num+right, cur_len);
max=Math.max(max, cur_len);
}
}
return max;
}
思路2:Set
把nums中的数存入set,过滤掉重复的元素。
读取每个num,判断num-1是否在set中:如果在,跳过;如果不在,判断num+1 +2… 直到在set中找不到,记录最大长度。
代码2: public int longestConsecutive(int[] nums) {
int max=0;
Set<Integer> set = new HashSet<Integer>();
for(int num:nums)
set.add(num);
for(int num:nums)
{
if(set.contains(num-1))
continue;
else{
int len=0;
while(set.contains(num++)){
len++;
}
max=Math.max(max, len);
}
}
return max;
}
补充:题目要求O(n),但是在解题过程中,使用contains是不影响时间复杂度的。