• [LeetCode] 128. 最长连续序列


    题目描述

    给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

    请你设计并实现时间复杂度O(n) 的算法解决此问题。

    示例 1:

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

    示例 2:

    输入:nums = [0,3,7,2,5,8,4,6,0,1]
    输出:9
    
    • 1
    • 2

    提示:

    • 0 <= nums.length <= 105
    • -109 <= nums[i] <= 109

    思考

    第一反应:对nums进行排序,然后查找最大序列。

    但是时间复杂度为 O ( n l o g n ) \Omicron (nlogn) O(nlogn)

    然后想一下,可以枚举每个数字,比如x。然后查看x+1,x+2,x+3是否出现过。

    朴素的话时间复杂度为 O ( n 2 ) \Omicron (n^2) O(n2)

    通过剪枝,如果处理x, 存在x-1的话,肯定不用进行这次遍历(因为结果肯定会小于从x-1开始)。时间复杂度 O ( n ) \Omicron (n) O(n)

    然后还可以使用并查集。比如2,3,4在同一个集合。7,8,9,10在一个集合。但是需要维护集合大小。

    代码实现

    感觉第三种实现比较有意思。虽然实际上写起来就感觉运行会很慢。权当复习并查集了

    //
    // Created by Anti on 2023/9/1.
    //
    #include "gtest/gtest.h"
    #include "logger.h"
    
    /**
     * @description 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
     * 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
     */
    class Solution {
    private:
        std::unordered_map father_;
        std::unordered_map size_; // 所在并查集的大小
        int max_size_{}; // 最大的并查集大小
        /**
         * 返回x的祖先。约定祖先较小。
         * @param x
         * @return
         */
        auto get_root(int x) -> int {
            if(father_[x]==x) {
                return x;
            }
            return father_[x] = get_root(father_[x]);
        }
    public:
        int longestConsecutive(std::vector& nums) {
            max_size_ = !nums.empty();
            for(const auto &num:nums) {
                father_[num] = num;
                size_[num] = 1;
            }
            for(const auto &num:nums) {
                auto y = num+1;
                if(father_.count(num+1)) {
                    auto father_x = get_root(num);
                    auto father_y = get_root(y); // 1 3 5 4
                    if(father_x!=father_y) {
                        if(father_x > father_y) {
                            std::swap(father_x, father_y);
                        }
                        father_[father_y] = father_x;
                        size_[father_x] += size_[father_y];
                        max_size_ = std::max(max_size_, int(size_[father_x]));
                    }
                }
            }
            return max_size_;
        }
    };
    
    TEST(S128,SAMPLE1) {
        Solution s;
        std::vector nums = {100,4,200,1,3,2};
        EXPECT_EQ(s.longestConsecutive(nums),4);
    }
    
    TEST(S128,SAMPLE2) {
        Solution s;
        std::vector nums = {0,3,7,2,5,8,4,6,0,1};
        EXPECT_EQ(s.longestConsecutive(nums),9);
    }
    
    TEST(S128,TRICK1) {
        Solution s;
        std::vector nums = {0};
        EXPECT_EQ(s.longestConsecutive(nums),1);
    }
    TEST(S128,TRICK2) {
        Solution s;
        std::vector nums = {};
        EXPECT_EQ(s.longestConsecutive(nums),0);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
  • 相关阅读:
    pthead 亲和性设置详解 pthread_attr_setaffinity_np pthread_setaffinity_np
    vuex的安装和使用
    Ubuntu 微调训练ChatGLM3大语言模型
    ByteV数字孪生实际应用案例-智慧矿山篇
    当一名阿里P9是什么样的体验?
    【教学类-19-02】20221127《ABCABC式-规律排序-A4竖版2份》(中班)
    Redis 设计与实现
    RocketMQ安装使用
    React 组件的3大属性: state
    一口气搞懂分库分表 12 种分片算法,大厂都在用
  • 原文地址:https://blog.csdn.net/AntiO2/article/details/132632325