当前位置: 首页 > news >正文

算法练习-最长连续序列

原题连接:128. 最长连续序列 - 力扣(LeetCode)

问题描述

给定一个未排序的整数数组 nums,你需要找出数字连续的最长序列的长度。注意:这个序列不要求元素在原数组中连续,但数字必须是连续的整数(例如,[1, 2, 3, 4])。要求算法的时间复杂度为 O(n),这意味着你不能使用排序(因为排序通常是 O(n log n)),必须使用更高效的方法。

示例分析

  • ​示例1​​:nums = [100, 4, 200, 1, 3, 2]

    • 最长连续序列是 [1, 2, 3, 4],长度为 4。

  • ​示例2​​:nums = [0, 3, 7, 2, 5, 8, 4, 6, 0, 1]

    • 最长连续序列是 [0, 1, 2, 3, 4, 5, 6, 7, 8],长度为 9(注意重复的 0 只算一次)。

  • ​示例3​​:nums = [1, 0, 1, 2]

    • 最长连续序列是 [0, 1, 2],长度为 3(重复元素不影响序列长度)。

方法思路:使用哈希集合

为了达到 O(n) 的时间复杂度,我们使用一个哈希集合(HashSet)来存储所有数字。哈希集合允许我们以 O(1) 的时间检查某个数字是否存在。基本思路是:

  1. ​将数组转换为集合​​:这样可以去重,并快速查找数字。

  2. ​查找序列起点​​:对于每个数字,如果它的前一个数(即 num - 1)不在集合中,那么它可能是一个连续序列的起点。

  3. ​扩展序列​​:从起点开始,逐个检查后一个数(即 num + 1num + 2等)是否在集合中,并计算序列长度。

  4. ​更新最大长度​​:在遍历过程中,记录遇到的最长序列长度。

为什么这样是 O(n)?因为每个数字最多被访问两次(一次在遍历中,一次在扩展序列时),所以总时间复杂度是 O(n)。

代码实现(Python)

以下是 Python 代码,逐行解释:

def longestConsecutive(nums):# 如果数组为空,直接返回0if not nums:return 0# 创建一个集合,存储所有数字(去重)num_set = set(nums)max_length = 0  # 初始化最大长度# 遍历集合中的每个数字for num in num_set:# 检查当前数字是否是序列的起点:即前一个数不在集合中if num - 1 not in num_set:current_num = numcurrent_length = 1# 扩展序列:检查后一个数是否在集合中while current_num + 1 in num_set:current_num += 1current_length += 1# 更新最大长度max_length = max(max_length, current_length)return max_length

代码解释:

  • ​第2-4行​​:处理空数组的情况,直接返回0。

  • ​第6行​​:将数组 nums转换为集合 num_set,这样可以去重并实现 O(1) 的查找。

  • ​第7行​​:初始化 max_length为0,用于记录最长序列长度。

  • ​第9行​​:遍历集合中的每个数字(注意:遍历集合而不是原数组,以避免重复处理)。

  • ​第11-12行​​:检查当前数字 num是否是序列的起点。如果 num - 1不在集合中,说明 num是一个起点。

  • ​第13-18行​​:从起点开始,通过 while循环扩展序列,检查 current_num + 1是否在集合中,并增加当前序列长度 current_length

  • ​第20行​​:更新最大长度 max_length

  • ​第22行​​:返回最终结果。

复杂度分析

  • ​时间复杂度​​:O(n)。虽然有一个嵌套的 while循环,但每个数字最多被访问两次(一次在外部循环,一次在内部循环),所以总操作次数是线性的。

  • ​空间复杂度​​:O(n)。因为使用了一个集合来存储数字,最坏情况下集合大小为 n。

示例演练

以示例1 nums = [100, 4, 200, 1, 3, 2]为例:

  1. 集合为 {100, 4, 200, 1, 3, 2}

  2. 遍历集合:

    • 数字100:100-99=1不在集合中,所以是起点。扩展序列:101不在集合中,序列长度1。

    • 数字4:4-3=1在集合中?是的(3在集合中),所以不是起点,跳过。

    • 数字200:200-199=1不在集合中,所以是起点。扩展序列:201不在集合中,序列长度1。

    • 数字1:1-0=0不在集合中,所以是起点。扩展序列:2在集合中,3在集合中,4在集合中,5不在集合中。序列长度4。

    • 数字3和2:已经被处理过(因为不是起点),跳过。

  3. 最大长度为4。

注意事项

  • ​重复元素​​:集合自动去重,所以重复元素不会影响结果。

  • ​负数和大数​​:算法处理负数和大数没有问题,因为集合查找是 O(1)。

  • ​边界条件​​:如果数组为空,直接返回0。

http://www.dtcms.com/a/347784.html

相关文章:

  • 最短路径和关键路径的算法
  • Linux学习:信号的保存
  • 【什么是大模型自注意力机制?】
  • 腾讯wxg后台开发面经
  • A Large Scale Synthetic Graph Dataset Generation Framework的学习笔记
  • JavaSpring+mybatis+Lombok,实现java架构[保姆教程]
  • KVM虚拟化:提升企业效率的利器
  • 编程刷题-P1746 离开中山路 BFS/最短路径
  • 数据结构算法:顺序表
  • 电脑零广告快响应提速(一)之卸载搜狗输入法使用RIME—东方仙盟
  • qt ElaWidgetTools第一个实例
  • linux进程调度相关头文件sched.h介绍与使用指南
  • 油猴(tampermonkey)脚本下载及安装使用教程!绿色版
  • [python编程] 零基础入门面向对象
  • Python面向对象高级编程——定制类
  • 本地部署开源书签管理工具 LinkAce 并实现外部访问( Windows 版本)
  • git实战问题(6)git push 时发现分支已被更新,push失败了怎么办
  • EPWpy 安装教程
  • 原初书写与符号嬗变:文字学理论的多维透视与当代重估
  • 【LeetCode】24. 两两交换链表中的节点
  • 青少年机器人技术(五级)等级考试试卷(2021年12月)
  • Linux:4_进程概念
  • Python 文件操作全解析:模式、方法与实战案例
  • openharmony之启动恢复子系统详解
  • 控制建模matlab练习14:线性状态反馈控制器-③极点配置
  • 河南萌新联赛2025第(六)场:郑州大学
  • nodejs 集成mongodb实现增删改查
  • 基于深度学习的中草药识别系统:从零到部署的完整实践
  • CA6150主轴箱系统设计cad+设计说明书
  • Java 学习笔记(基础篇8)