题目描述:
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