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.
給你一個n個數的亂序序列,O(N)找出其中最長的連續序列的長度。
例如給你[100, 4, 200, 1, 3, 2]
,那麼最長的連續序列爲[1, 2, 3, 4]
,所以返回4。
思路:
最簡單直接的想法是:將數組排序,然後掃一遍排好序的序列,從中找出最長的即可,這樣的話時間是O(nlogn)+O(n),顯然不符合題目要求,會超時。
那怎麼樣不排序就能做出來呢?
我們先拋開算法,想想自己會怎麼找,當數組很小,你可以記住所有的數。例如上面的例子。我們自己找的話,看到一個數例如4,我們會下意識的去找有沒有3和5,有3那麼就會繼續找2,以此類推,直到找不到爲止,找過的數以後我就不會再去找了,例如1,2,3,4都在找4的時候一起找過了,所以我後面只考慮100,和200,這樣每個數其實我只找了一遍。 如果我能夠在O(1)的時間判斷是否存在一個數,那麼我找最長的序列的時間就是O(N)的。現在好辦了,如何實現在O(1)的時間查找一個數?Answer:hash table。對,我們只要將數存儲在hashmap或者hashset裏面就OK了。這裏只要用hashset就夠了,我們並不需要鍵值對的映射。好了,僞代碼:
1. 預處理:建hashset,將數組元素全部加進hashset裏頭
2. For each element e in array:
2.1 if e in hashset:
find e-1, e+1 in hashset until cannot go further anymore
remove these elements from hashset
2.2 if the sequence is longer all previous sequences ,update max length
另外從這一題學到的C++的東西:
hash_*系列例如hash_map,hash_set 等已經被desperate被廢棄了,C++11用unordered_map,unordered_set等來替代。
上代碼:
class Solution {
public:
int longestConsecutive(vector<int> &num) {
unordered_set<int> set; // 不能改成hash_set
unordered_set<int>::const_iterator it;
for(int i = 0;i<num.size();i++) {
if(set.find(num[i]) == set.end()) {
set.insert(num[i]);
}
}
int maxLen = 0;
for(int i=0;i<num.size();i++) {
int tmp = 1;
if(set.find(num[i]) != set.end()) {
int cur = num[i] + 1;
while(set.find(cur) != set.end()) {
set.erase(cur);
tmp++;
cur++;
}
cur = num[i]-1;
while(set.find(cur) != set.end()) {
set.erase(cur);
tmp++;
cur--;
}
if(tmp>maxLen)
maxLen = tmp;
}
}
return maxLen;
}
};