问题:
求未排序数列中,最长连续数列长度。
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 };