• leetcode 128最长连续序列


    方法一:使用快排:

    //排序法,时间O(nlogn),使用STL,只是验证一下思想,非正解;
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            int res=0;
            for(int i=0;i<nums.size();i++){
                int step=0,len=1;
                while(i+step!=nums.size()-1&&nums[i+step+1]-nums[i+step]<=1){
                    if(nums[i+step]+1==nums[i+step+1]) len++;
                    step++;
                }
                res=max(res,len);
                i+=step;
            }
            return res;
        }
    };

     方法二:使用并查集如题所说达到O(n)

    方法三:使用哈希表O(n)

    //哈希表结合染色,建立一个哈希表,然后遍历之后计数每个元素周围所有相邻元素并染色,记录个数;O(n)复杂度
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            int len=nums.size();
            if(len<=1) return len;
            unordered_map<int,int> m;
            int res=0;
            for(int n:nums)
                m[n]=1;
            for(int n:nums){
                int i=n,j=n;
                int cnt=1;
                if(m[n]==0)
                    continue;
                else
                    m[n]=0;
                while(m[i+1]==1){
                    i++;
                    m[i]=0;
                }
                    
                while(m[j-1]==1){
                    j--;
                    m[j]=0;
                }
                    
                cnt=i-j+1;
                res=cnt>res?cnt:res;
            }
            return res;
        }
    };

    别人家的哈希表:

    /****
    通过哈希表记录边界信息
    
    neither i+1 nor i-1 has been seen: m[i]=1;
    
    both i+1 and i-1 have been seen: extend m[i+m[i+1]] and m[i-m[i-1]] to each other;
    
    only i+1 has been seen: extend m[i+m[i+1]] and m[i] to each other;
    
    only i-1 has been seen: extend m[i-m[i-1]] and m[i] to each other.
    
    *****/
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            int len=nums.size();
            if(len<=1) return len;
            unordered_map<int,int> m;
            int res=0;
            for(int i:nums){
                if(m[i]) continue;
                //后面表达式为将m[i]和这一段连续序列的边界全部赋值为他的长度
                //边界只可能为m[i-m[i-1]]到m[i+m[i+1]],m[i]到m[i+m[i+1]],m[i-m[i-1]]到m[i]这几种情况,因此更新三者的值为新连续序列的长度即可
                //又因为没有的元素哈希值为0,所以m[i]左右元素的m[i-1]+m[i+1]+1为新序列的长度;
                res=max(res,m[i]=m[i+m[i+1]]=m[i-m[i-1]]=m[i-1]+m[i+1]+1);
            }
            return res;
        }
    };

     别人家的使用hashset 和 hashtable:

    hashset:

    /****
    通过哈希set
    
    将nums转化为哈希set,然后对哈希set进行遍历,寻找连续片段的左边界,然后num+1进行遍历。
    可以证明每个元素将被访问2遍,for中一遍,while一遍,所以time O(n),space O(n);
    由于int会产生越界,可以使用long,也可以进行边界检测,INT_MAX break;
    
    
    *****/
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            int res=0;
            unordered_set<int> h(nums.begin(),nums.end());
            for(int num:nums){
                int l=0;
                if(!h.count(num-1)){
                    while(h.count(num)!=0){
                        ++l;
                        if(num==INT_MAX) break;
                        ++num;
                    }
                    res=res>l?res:l;
                }
            }
            return res;
        }
    };

    hashtable:

    /****
    通过哈希table
    
    solution 1: hashtable (key,len)
    case1: no neighboors
    h[num]=1;
    case2: one neighboor
    l=h[num-1] or r=h[num+1]
    h[num]=h[num-1]=l+1 or h[num]=h[num+1]=r+1
    case3: two neighboors
    l=h[num-1]
    r=h[num+1]
    h[num]=h[num-1]=h[num+1]=l+r+1
    
    
    
    *****/
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            int res=0;
            unordered_map<int,int> h;
            for(int num:nums){
                if(h[num]!=0) continue;
                int l=h[num-1];
                int r=h[num+1];
                
                int t=l+r+1;
                
                h[num]=h[num+r]=h[num-l]=t;
                res=res>t?res:t;
            }
            return res;
        }
    };

     哈希set

    /****
    通过哈希set
    
    将nums转化为哈希set,然后对哈希set进行遍历,寻找连续片段的左边界,然后num+1进行遍历。
    可以证明每个元素将被访问2遍,for中一遍,while一遍,所以time O(n),space O(n);
    由于int会产生越界,可以使用long,也可以进行边界检测,INT_MAX break;
    
    
    *****/
    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            int res=0;
            unordered_set<int> h(nums.begin(),nums.end());
            for(int num: nums){
                int l=0;
                if(h.count(num-1)==0){
                    while(h.count(num)>0){
                        l++;
                        if(num==INT_MAX) break;
                        num++;
                    }
                }
                res=res>l?res:l;
            }
            return res;
        }
    };

    有道词典
    solution 1: has ...
    详细X
      解决方案1:哈希表(关键,len) case1:没有neighboorsh (num) = 1,例2:一个neighboorl = h [num-1]或r = h (num + 1) h (num) = h [num-1] = l + 1或h (num) = h (num + 1) = r + 1 case3:两个neighboorsl = h [num-1] r = h (num + 1) h (num) = h [num-1] = h (num + 1) = l + r + 1         * * * * * /类解决方案{公众:int longestConsecutive(向量< int > & num) {int res = 0; unordered_map < int, int > h;为(int num: num){如果(h (num) ! = 0)继续;int l = h [num-1]; int r = h (num + 1); int t = l + r + 1; h (num) = h (num + r) = h [num-l] = t; res = res > t ? res: t;}返回res;}};
  • 相关阅读:
    如何用Chrome浏览器下载网页音乐视频
    《C语言深度解剖》学习笔记之函数
    《C语言深度解剖》学习笔记之内存管理
    《C语言深度解剖》学习笔记之指针和数组
    《C语言深度解剖》学习笔记之预处理
    《C语言深度解剖》学习笔记之符号
    《C语言深度解剖》学习笔记之关键字
    CKA1.20版本2021年1月31日最新版本真题,第三题升级master节点
    CKA1.20版本2021年1月31日最新版本真题,第一题RBAC
    Linux之curl命令
  • 原文地址:https://www.cnblogs.com/joelwang/p/10876881.html
Copyright © 2020-2023  润新知