题目描述:
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.
初次看到这个题的时候,不得不说的是,我一点思路都没有,除了排序,似乎根本没有其他的方法(这可能跟我排斥hash比较有关系)。
接着我实现了一下的几个版本:
Section 1: 既然想不到O(n)的算法,那就干脆直接用排序好了.
int longestConsecutive(vector<int> &num)
{
sort(num.begin(),num.end());
for(int i = 0; i < num.size() ;++i)
cout << num[i] << " ";
cout << endl;
int i = 0 ;
int maxC = 0;
int count = 0;
while(i < num.size())
{
count = 1;
while(i < num.size())
{
int cur = num[i];
int j = i + 1;
while(j < num.size() && cur == num[j])
j += 1;
if(j == num.size()) break;
if(cur+1 == num[j])count += 1;
i = j;
}
if(count > maxC) maxC = count;
i += 1;
}
return maxC;
}
显然这样的复杂度是不符合要求的,直接就是O(nlogn)了。(因为sort函数采用的是快排的思想。)
发现网上大多数大神们写的思想都非常的简单,直接用一个C++的set容器就解决了,看完大神们的做法,自己重新写了一遍:
private:
int count(int current, unordered_set< int > & hashSet, bool up)
{
int c = 0;
while(hashSet.find(current) != hashSet.end())
{
hashSet.erase(current);
c += 1;
if(up) current++;
else current--;
}
return c;
}
int longestConsecutive(vector<int> &num)
{
int len = num.size();
if(len == 0)return 0;
unordered_set<int> hashSet;
for(int i = 0 ; i < len ; ++i)
{
hashSet.insert(num[i]);
}
int maxC = 1;
int temp = 0;
for(int i = 0 ; i < len ; ++i)
{
int current = num[i];
hashSet.erase(current);
temp = 1;
temp += count(current + 1, hashSet, true);
temp += count(current - 1, hashSet, false);
maxC = (maxC > temp)?maxC:temp;
}
return maxC;
}
这样对于每数组中的每一个数据,分别寻找它的“增大方向”以及“减小方向”的最大可以连续延伸的数据。
总结:
对于这样的题目,首先想到排序是很自然的,可是要想到用hash对于我来说很难,因为我非常讨厌hash。
正因为这样的一个题目,我也更进一步的认识了C++的容易unordered_set.查看了一下它的功能,发现真的是很强大的,至于实现的原理,看过几篇博客的介绍,很不错,推荐这篇给大家:
http://blog.csdn.net/mmzsyx/article/details/8240071