zoukankan      html  css  js  c++  java
  • 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 };
  • 相关阅读:
    二分搜索
    中文分词 (机械传统方法 )正向最大匹配
    推荐引擎概述(转自IBM worker)
    linux OS 多线程学习
    FastReport.Net传递报表参数
    MSSQL 2008 镜像的客户端数据库连接字符串
    FastReport.Net自动行高
    ReSharper 8.0开发版 ReSharper 8.0 Early Access
    客户端FastReport.Net默认界面语言
    ReSharper 7.0 正式版发布
  • 原文地址:https://www.cnblogs.com/habibah-chang/p/12592290.html
Copyright © 2011-2022 走看看