Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
Clarification
Your algorithm should run in O(n) complexity.
类似题目 最长递增子序列(LIS)
思路就是:
1.将num存到unordered_map(或者unordered_set)中;
2.
- 对于num的每个数(没有访问过的)n
- 在unordered_map中查找n+1,n-1在不在,循环进行这一步,查找到的数在unordered_map中去掉,可以统计出n导出的连续的数的长度len,如果len>maxLen,更新maxLen。
需要注意几点:
1.unordered_map、unordered_set和hash_map、hash_set
见我的博客数据结构:hash_map原理 C++中map、set、hash_map、hash_set、unordered_map、unordered_set通俗辨析
2.以前看一直以为erase函数的参数只能是迭代器,其实erase的参数还可以是key_type
http://www.cplusplus.com/reference/map/map/erase/
std::map::erase
(1)
iterator erase (const_iterator position);
(2)
size_type erase (const key_type& k);
(3)
iterator erase (const_iterator first, const_iterator last);
For the key-based version (2), the function returns the number of elements erased,
which in map containers is at most 1.
class Solution {
public:
/**
* @param nums: A list of integers
* @return an integer
*/
int longestConsecutive(vector<int> &num) {
// write you code here
unordered_map<int,bool> tmpNum;
for(int n:num){
tmpNum[n]=false;
}
int maxLen=0;
for(int n:num){
if(tmpNum[n]) continue;
int len=0;
queue<int> Q;
Q.push(n);
while(!Q.empty()){
int i=Q.front();
Q.pop();
/*tmpNum.find(i)->second==false 不判断会出现死循环*/
if(tmpNum.find(i)!=tmpNum.end() && tmpNum.find(i)->second==false){
len++;
tmpNum[i]=true;
Q.push(i+1);
Q.push(i-1);
}
}
if(len>maxLen){
maxLen=len;
}
}
return maxLen;
}
};
理解成图的深度搜索。数字是点,邻边是相邻的数字。
class Solution {
public:
/**
* @param nums: A list of integers
* @return an integer
*/
int longestConsecutive(vector<int> &num) {
// write you code here
unordered_map<int,bool> tmpNum;
for(int n:num){
tmpNum[n]=false;
}
int maxLen=0;
for(int n:num){
if(tmpNum[n]) continue;
int len=0;
int up=n;
while(tmpNum.find(up)!=tmpNum.end()){
//tmpNum.erase(up);
len++;
tmpNum[up]=true;
up++;
}
int down=n-1;
while(tmpNum.find(down)!=tmpNum.end()){
//tmpNum.erase(down);
len++;
tmpNum[down]=true;
down--;
}
if(len>maxLen){
maxLen=len;
}
}
return maxLen;
}
};