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.
最初的实现是这样的:
int longestConsecutive(vector<int>& nums) {
unordered_map<int,bool> maps;
int ans = 0, t, l;
for(int i= 0 ; i < nums.size() ; i ++) {
for( t = nums[i], l = 1 ; maps.find(--t) != maps.end() ; l ++);
for( t = nums[i]; maps.find(++t) != maps.end(); l++);
ans = l > ans ? l : ans;
maps[nums[i]] = true;
}
return ans;
}
很不幸,上面的这个实现时超时的,其超时的本质原因是导致一些连续的子序列会重复被查询到。
看了一些牛人的实现,对代码进行一定的调整,如下:
这个代码在leetcode 是Accepted 的。
int longestConsecutive(vector<int>& nums) {
unordered_map<int,bool> maps;
int ans = 0, t, l;
for(int i : nums) maps[i] = false;
for(int i : nums) {
if(maps[i]) continue;
maps[i] = true;
for(t = i - 1 , l = 1 ;
(maps.find(t) != maps.end()) && (maps[t] == false);
l++, maps[t] = true , t--);
for(t = i + 1 ;
(maps.find(t) != maps.end()) && (maps[t] == false);
l++, maps[t] = true, t++);
ans = l > ans ? l : ans;
}
return ans;
}
参考的牛人实现的代码如下:
int longestConsecutive(const vector<int> &nums) {
unordered_map<int, bool> used;
for (auto i : nums) used[i] = false;
int longest = 0;
for (auto i : nums) {
if (used[i]) continue;
int length = 1;
used[i] = true;
for (int j = i + 1; used.find(j) != used.end(); ++j) {
used[j] = true;
++length; }
for (int j = i - 1; used.find(j) != used.end(); --j) {
used[j] = true;
++length; }
longest = max(longest, length);
}
return longest;
}