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(nlogn)。不满足线性要求。
方案二:
要求线性方法,先尝试能否改变策略来求得。正如LeetCode | First Missing Positive 那样。但是很可惜,没有想到。
最常用的是空间换时间,就利用哈希映射后,再遍历的方法来求解。
先求出max和min,然后建立大小为max-min+1空间的容量,将数据映射到其中。
再遍历整个哈希数组,求出连续的最大值。很可惜,这样太浪费空间了。用c的话,没有什么好的方法。但c++有相应的容器。稍后讲解。
class Solution {
public:
int longestConsecutive(vector<int> &num) {
int min,max;
int n = num.size();
if(n == 0)
return 0;
min = max = num[0];
for(int i = 1;i < n;i++){
if(num[i] > max)
max = num[i];
else if(num[i] < min)
min = num[i];
}
int *h = new int[max-min+1];
for(int i = 0;i < n;i++)
h[num[i]-min] = 1;
int maxlen = 0;
for(int i = 0;i < max-min+1;i++){
int len = 0;
while(i < max-min+1 && h[i] == 0) //找到第一个为1的数
i++;
while(i < max-min+1 && h[i] == 1){ //计算连续1的个数
i++;
len++;
}
if(len > maxlen) //更新最大值
maxlen = len;
}
return maxlen;
}
};
方案三:
C++中有set集,有的网友set<int> map; 但由于其也是插入,造成了查找时间复杂度也是logn。可以用的是unordered_set,查找时间复杂度为O(1)。找到后,先清除标记,然后相应的查找++的数,和–的数。最后求和。
class Solution{
public:
int longestConsecutive(vector<int> &num) {
int ans = 0;
for(int i = 0;i < num.size();i++)
map.insert(num[i]);
for(int i = 0;i < num.size();i++){
int count = findBound(num[i],true) + findBound(num[i]+1,false);
ans = ans > count ? ans : count;
}
}
int findBound(int n,bool asc){
int count = 0;
while(map.find(n) != map.end()){
count++;
map.erase(n);
if(asc)
n--;
else
n++;
}
return count;
}
private:
unordered_set<int> map;
};