问题描述:
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.
我首先想到的是一个O(n2)的方法:就是遍历每个元素,查看该元素是否与前面的set中相邻(+-为1),如果是,将其加入到该set中,如果不是,新建一个set。
然后我又想,这里面大量的时间实际上是花在了遍历set中,如果将set变成一个hash表,按查找时间就将为了O(1),此时时间复杂度大概为O(nlogn)。这个想法,比较糟糕的地方是虽然查找时间降为了O(1),但是需要不断的将新元素加入到对应的key set中,这样很不方便实现,而且需要递归的循环下去。
但是在网上看到了其他人的想法,才觉得转换一个思路真的太奇妙了。同样是利用hash表。首先对序列做一个预处理,即将序列中元素添加到hashset中,然后再做一次遍历,如果某元素在hashset中,那么查找它的前一个元素,如果存在,就删除该元素。然后计数加1;
代码如下:
public int longestConsecutive(int[] nums) {
HashSet<Integer> sets = new HashSet<Integer>();
//prepare for process
for(int i = 0;i<nums.length;i++){
sets.add(nums[i]);
}
int tmp;
int value,realValue = 1;
for(int j = 0;j<nums.length;j++){
tmp = nums[j];
value = 1;
if(!sets.contains(tmp))//deleted already
continue;
while(true){
if(sets.contains(tmp-1)){
value++;
sets.remove(tmp-1);
tmp = tmp-1;
}
else
break;
}
tmp = nums[j];
while(true){
if(sets.contains(tmp+1)){
value++;
sets.remove(tmp+1);
tmp = tmp+1;
}else
break;
}
realValue = (realValue>value)?realValue:value;
}
return realValue;
}