128. Longest Consecutive Sequence

问题:

求未排序数列中,最长连续数列长度。

Example:
Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

  

解法1:

方针:求每段子序列的左边界,以左边界开始递增,判断是否存在在序列中,直到右边界,求len,对每次的len求最大

1.将数列放入unordered_set的集合中

2.依次读入nums的数字,在set中找是否当前数字i为连续最小,即不存在 i-1 在整个数列中。

3.如果2成立,则 i++ 依次判断是否存在,直到不存在,记录到现在为止的 len,res=max(res, len)求的目前为止最大的 len

  如果2不成立,则continue,进行遍历下一个nums的数字

4.遍历完,res为所求

 

参考代码:

 1 class Solution {
 2 public:
 3     int longestConsecutive(vector<int>& nums) {
 4         unordered_set<int> m;
 5         int res = 0;
 6         for(int i:nums){
 7             m.insert(i);
 8         }
 9         for(int i:nums){
10             if(!m.count(i-1)){
11                 int j=i+1;
12                 int len=1;
13                 while(m.count(j)){
14                     j++;
15                     len++;
16                 }
17                 res=max(res, len);
18             }
19         }
20         return res;
21     }
22 };

 

解法2:

方针:对每个值,在其所在连续子序列的左右边界上记录该子序列的最大长度,(由于只判断和更新连续序列的边界两点,因此)只关注边界两点的记录内容,并更新,不要求内部节点的记录值也都实时正确。

1.建立unordered_map,记录每个nums的值i到边界的长度len,m[i]=len

2.如果len为0,则第一次遍历以及处理i的边界。如果len不为0,则证明已经处理过i,continue不在重复处理

3.对于未处理的i,

判断 m[i-1] 和 m[i+1] 所记录的边界,

<1> 如果两侧均没记录过,那么 m[i] =1,该节点目前为止为独立节点。

<2> 如果有一侧记录过,那么 延展该侧到 i 为止,i 为其中一个边界,而另一个边界需要更新边界长度为 原来长度(m[i-1])  +1

m[i-1]!=0: i-1的原左边界为 i-1 -m[i-1] +1 = i-m[i-1], 更新该点的m值 m[ i-m[i-1] ] =  m[i-1]+1 ;

★原来的左边界i-m[i-1],和右边界 i-1 的m值应该都为同样的值,指示两边界的距离:m[i-1]

m[i+1]!=0: i+1的原右边界为 i+1 +m[i+1] -1 = i+m[i+1], 更新该点的m值 m[ i+m[i+1] ] =  m[i+1]+1 ;
★原来的右边界i+m[i+1],和左边界 i+1 的m值应该都为同样的值,指示两边界的距离:m[i+1]

<3> 如果两测都记录过,那么两侧的最左边界和最右边界的m值都需要更新,同时要更新当前节点i的m值

更新为,原左侧连续序列的边界m[i-1]+右侧连续序列的边界m[i+1]在加上i节点 +1

即m[i-1]+m[i+1]+1

更新对象:

原左侧序列的最左边界:m[ i-m[i-1] ] 
原右侧序列的最右边界:m[ i+m[i+1] ] 

当前i节点:m[ i ]

4.对每次求出的边界距离m[i]求最大,res=max(res, m[i])

5.遍历完,res为所求

参考代码:

 1 class Solution {
 2 public:
 3     int longestConsecutive(vector<int>& nums) {
 4         unordered_map<int, int> m;//key:nums value:bound_len
 5         int res=0;
 6         for(int i:nums){
 7             if(m[i]) continue;
 8             if(m[i-1]==0 && m[i+1]==0){
 9                 m[i]=1;
10             }else if(m[i-1]>0 && m[i+1]==0){
11                 m[i]=m[i-m[i-1]]+1;
12                 m[i-m[i-1]]=m[i];
13             }else if(m[i+1]>0 && m[i-1]==0){
14                 m[i]=m[i+m[i+1]]+1;
15                 m[i+m[i+1]]=m[i];
16             }else{
17                 m[i]=m[i-m[i-1]]+1+m[i+m[i+1]];
18                 m[i-m[i-1]]=m[i];
19                 m[i+m[i+1]]=m[i];
20             }
21             res = max(res, m[i]);
22         }
23         return res;
24     }
25 };

 

posted @ 2020-03-29 14:50  habibah_chang  阅读(110)  评论(0编辑  收藏  举报