128-最长连续序列(算法思路,优化和复杂度分析)

题目描述

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

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

示例 1:

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

示例 2:

ini 复制代码
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

思路

首先将数组元素都添加到set中,借助set高效的查找

再对数组元素进行遍历,找到连续序列的起点或终点,这样可以减少不必要的操作,因为从起点(连续序列中的最小数字)向上遍历或者从终点向下遍历能确定当前连续序列的最大长度

复杂度分析

时间复杂度

1. 创建 Set

  • 操作 :遍历数组 nums 并将每个元素添加到 Set 中。
  • 时间复杂度 :O(N),其中 N 是数组 nums 的长度。

2. 遍历 Set 并查找最长连续序列

  • 外层循环 :遍历 Set 中的每个元素,时间复杂度为 O(N)。
  • 内层循环
    • 只有在当前数字 n 是某个序列的起始点(即 n - 1 不在 Set 中)时,才会进入内层 while 循环。
    • 每个数字最多只会被访问一次,无论是作为外层循环的一部分还是在内层循环中被递增处理。
    • 因此,内层循环总的操作次数不会超过 N 次。
  • 总时间复杂度
    • 外层循环:O(N)
    • 内层循环:O(N)(由于每个数字最多被处理一次)
    • 综合总时间复杂度:O(N) + O(N) = O(N)

空间复杂度

  • Set :存储了数组 nums 中的所有唯一元素,空间复杂度为 O(N)。
  • 其他变量
    • maxLencurLen:常数空间,O(1)。
  • 总空间复杂度O(N)

为什么时间复杂度是 O(N) 而不是 O(N²)

  • 虽然有两层循环,但内层循环的次数是由外层条件控制的,即只有在找到序列的起始点时才会执行。
  • 每个元素最多只会被检查一次。在内层循环中,n 会被递增,并且这些递增操作不会重叠或重复处理相同的元素。

code

javascript 复制代码
/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function(nums) {
    const set = new Set()
    for(let n of nums){
        set.add(n)
    }
    let maxLen = 0
    for(let n of set.values()){
        let curLen = 1
        if(!set.has(n - 1)){
            while(set.has(n + 1)){
                n++
                curLen++
            }
        }
        maxLen = Math.max(maxLen, curLen)
    }
    return maxLen
};
相关推荐
小徐不徐说4 分钟前
动态规划:从入门到精通
数据结构·c++·算法·leetcode·动态规划·代理模式
guguhaohao14 分钟前
排序算法,咕咕咕
数据结构·算法·排序算法
前端小巷子15 分钟前
深入 npm 模块安装机制
前端·javascript·面试
小新学习屋35 分钟前
《剑指offer》-数据结构篇-树
数据结构·算法·leetcode
好心的小明41 分钟前
【深度之眼机器学习笔记】04-01-决策树简介、熵,04-02-条件熵及计算举例,04-03-信息增益、ID3算法
笔记·算法·决策树
恣艺2 小时前
LeetCode 1074:元素和为目标值的子矩阵数量
算法·leetcode·矩阵
queenlll3 小时前
P1064 [NOIP 2006 提高组] 金明的预算方案 题解
算法
ZzMemory3 小时前
一文搞懂前端开发必备的导入导出方式
前端·面试·前端工程化
Alfred king4 小时前
面试150 IPO
面试·职场和发展·贪心·数组··排序
练习时长两年半的程序员小胡4 小时前
JVM 基础架构全解析:运行时数据区与核心组件
java·jvm·面试