• 【LeetCode-数组】最长连续序列


    题目描述

    给定一个未排序的整数数组,找出最长连续序列的长度。
    要求算法的时间复杂度为 O(n)。
    示例:

    输入: [100, 4, 200, 1, 3, 2]
    输出: 4
    解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。
    

    题目链接: https://leetcode-cn.com/problems/longest-consecutive-sequence/

    思路1

    使用哈希表来做,并且使用 c++ 的 map 来构造哈希表。map 默认是按照 key 升序排序的。我们先将数组中的数字插入到 map 中,然后从头遍历 map,这样遍历得到的 key 序列就是一个有序序列。这样问题就转化成了在有序序列中找最长连续序列的长度。可以用动态规划来做:

    • 令当前最长连续序列的长度 ans = 1,设置计数器 cnt = 1,表示当前连续序列的长度;
    • 遍历哈希表:
      • 如果当前元素的 key 和前一个元素的 key 相等,说明连续,cnt++;
      • 否则说明不连续,遇到了新的连续序列,则 ans = max(ans, cnt),cnt = 1;
    • 返回 max(ans, cnt);

    代码如下:

    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            if(nums.empty()) return 0;
    
            map<int, int> hash;
            for(int i=0; i<nums.size(); i++) hash[nums[i]]++;
    
            vector<int> dp(hash.size(), 0);
            auto it = hash.begin();
            int ans = 1;
            int cnt = 1;
            auto pre = hash.begin(); // 当前元素的前一个元素
            for(; it!=hash.end(); it++){
                if(it!=hash.begin()){
                    if(it->first - pre->first == 1){
                        cnt++;
                    }else{
                        ans = max(cnt, ans);
                        cnt = 1;
                    }
                }
                pre = it;
            }
            return max(ans, cnt);
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    思路2

    遍历数组 nums,当遍历当前元素 nums[i] 时,判断 nums[i]-1 是否在数组中,如果不在的话,循环判断 nums[i]+cnt 是否在数组中,如果 nums[i]~nums[i]+cnt 都在数组中,那么我们就找到了一个长度为 cnt 的连续序列。记录最长的 cnt 作为答案。可以用 set 来判断一个元素是否在数组中出现。
    代码如下:

    class Solution {
    public:
        int longestConsecutive(vector<int>& nums) {
            if(nums.empty()) return 0;
    
            unordered_set<int> s;
            for(int num:nums) s.insert(num);
    
            int ans = 1;
            for(int i=0; i<nums.size(); i++){
                if(s.count(nums[i]-1)==0){ // nums[i]-1 没有在数组中出现,这一步判断很重要
                    int cnt = 1;
                    int curNum = nums[i];
    
                    while(s.count(curNum+1)){
                        curNum++;
                        cnt++;
                    }
                    ans = max(ans, cnt);
                }
            }
            return ans;
        }
    };
    
    • 时间复杂度:O(n)
    • 空间复杂度:O(n)

    参考

    https://leetcode-cn.com/problems/longest-consecutive-sequence/solution/zui-chang-lian-xu-xu-lie-by-leetcode-solution/

    后记

    这是我刷的 LeetCode 的第 150 题,这段时间刷题速度明显下降了,接下来要加油。

  • 相关阅读:
    Solr的中英文分词实现
    乐观锁与悲观锁
    Keepalived + nginx实现高可用性和负载均衡
    Heartbeat实现集群高可用热备
    mongoDB 使用手册
    LVS+keepalived负载均衡
    keepalived工作原理和配置说明
    微信设置URL之WebApi方式
    RabbitMQ Windows下安装问题解决
    JSOM 中对各种字段操作
  • 原文地址:https://www.cnblogs.com/flix/p/13057764.html
Copyright © 2020-2023  润新知