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.
问题
给出一个未排序的整数数组,找出最长的连续元素序列的长度。
如:
给出[100, 4, 200, 1, 3, 2],
最长的连续元素序列是[1, 2, 3, 4]。返回它的长度:4。
你的算法必须有O(n)的时间复杂度 。
思路
- "排序转换成经典的动态规划问题"的话排序至少需要时间复杂度为O(nlog(n))——pass
- 利用c++中的set,直接会排序,并且没有重合的,但是set背后实现的原理牵扯到红黑树,时间复杂度不满足——pass
- 建立hash索引,把查找的元素周围的都访问个遍,求出个临时最大值跟全局最大值比较。当再次访问该段的元素的时候,直接跳过。这样保证时间复杂度为O(n),c++11中数据结构为unordered_set,保证查找元素的时间复杂度为O(1).
伪代码
建立无序集合existSet visitedSet分别表示原集合中包含的元素和已经访问了的元素 全局最大个数maxLen 顺序遍历原集合中的元素 临时计数count=1 如果该元素在visitedSet,停止往下执行,进行下一次循环 否则,把改元素小的并且在existSet中的元素存放在visitedSet中,count++ 把改元素大的并且在existSet中的元素存放在visitedSet中, count++ maxLen = max(maxLen, count)
1 class Solution { 2 public: 3 int longestConsecutive(vector<int> &num) { 4 int max=0; 5 std::unordered_set<int> visit; 6 std::unordered_set<int> exist; 7 for(int i=0;i<num.size();i++){ 8 exist.insert(num[i]); 9 } 10 for(int i=0;i<num.size();i++){ 11 if(visit.find(num[i])!=visit.end()){ 12 continue; 13 } 14 int count=1; 15 int left=num[i]-1; 16 while(exist.find(left)!=exist.end()){ 17 count++; 18 visit.insert(left); 19 left--; 20 } 21 int right=num[i]+1; 22 while(exist.find(right)!=exist.end()){ 23 count++; 24 visit.insert(right); 25 right++; 26 } 27 if(count>max) 28 max=count; 29 } 30 return max; 31 } 32 };