最长连续序列 (Longest Consecutive Sequence) - LeetCode 题解

题目描述

给定一个未排序的整数数组 nums,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。要求设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

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

示例 2:

输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9
解释:最长数字连续序列是 [0,1,2,3,4,5,6,7,8]。它的长度为 9。

示例 3:

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

解题思路

方法一:哈希集合(推荐)

  1. 哈希集合预处理

    • 将所有数字存入哈希集合中,实现O(1)时间复杂度的查找
    • 去重处理,避免重复数字的影响
  2. 寻找连续序列

    • 遍历数组中的每个数字
    • 对于每个数字,检查它是否是某个连续序列的起点(即num-1不在集合中)
    • 如果是起点,则向后查找连续的数字,计算当前连续序列的长度
    • 更新最长连续序列的长度
  3. 复杂度分析

    • 时间复杂度:O(n),每个数字最多被访问两次(一次在哈希集合中,一次在连续序列查找中)
    • 空间复杂度:O(n),用于存储哈希集合

方法二:排序法(不满足O(n)要求)

  1. 排序数组

    • 先对数组进行排序
    • 然后遍历排序后的数组,寻找最长连续序列
  2. 缺点

    • 时间复杂度为O(n log n),不满足题目要求
    • 仅作为对比思路提及

Go 代码实现

func longestConsecutive(nums []int) int {if len(nums) == 0 {return 0}// 创建哈希集合存储所有数字numSet := make(map[int]bool)for _, num := range nums {numSet[num] = true}longestStreak := 0// 遍历哈希集合中的每个数字for num := range numSet {// 检查当前数字是否是某个连续序列的起点if !numSet[num-1] {currentNum := numcurrentStreak := 1// 向后查找连续的数字for numSet[currentNum+1] {currentNum++currentStreak++}// 更新最长连续序列长度if currentStreak > longestStreak {longestStreak = currentStreak}}}return longestStreak
}func main() {// 示例测试nums1 := []int{100, 4, 200, 1, 3, 2}result1 := longestConsecutive(nums1)fmt.Println("Longest consecutive sequence length:", result1) // 输出: 4nums2 := []int{0, 3, 7, 2, 5, 8, 4, 6, 0, 1}result2 := longestConsecutive(nums2)fmt.Println("Longest consecutive sequence length:", result2) // 输出: 9nums3 := []int{1, 0, 1, 2}result3 := longestConsecutive(nums3)fmt.Println("Longest consecutive sequence length:", result3) // 输出: 3
}

测试用例

func TestLongestConsecutive(t *testing.T) {tests := []struct {input []intwant  int}{{[]int{100, 4, 200, 1, 3, 2}, 4},{[]int{0, 3, 7, 2, 5, 8, 4, 6, 0, 1}, 9},{[]int{1, 0, 1, 2}, 3},{[]int{}, 0},{[]int{1}, 1},{[]int{1, 3, 5, 7, 9}, 1},{[]int{1, 2, 3, 4, 5}, 5},{[]int{5, 4, 3, 2, 1}, 5},}for _, tt := range tests {got := longestConsecutive(tt.input)if got != tt.want {t.Errorf("longestConsecutive(%v) = %d, want %d", tt.input, got, tt.want)}}
}

复杂度分析

  1. 时间复杂度:O(n)

    • 创建哈希集合:O(n)
    • 遍历哈希集合:每个数字最多被访问两次(一次在哈希集合中,一次在连续序列查找中)
    • 总体时间复杂度为线性
  2. 空间复杂度:O(n)

    • 需要额外的哈希集合存储所有数字

优化思路

  1. 并行处理

    • 对于大规模数据,可以考虑将数组分割后并行处理
    • 需要处理边界条件和合并结果
  2. 内存优化

    • 如果数字范围有限,可以使用位图代替哈希集合
    • 减少内存使用,提高缓存命中率
  3. 流式处理

    • 对于无法一次性加载到内存的超大数据集
    • 可以使用外部排序和分段处理技术

总结

这道题考察了对哈希数据结构的灵活运用,关键在于如何高效地判断连续序列的起点和计算序列长度。通过使用哈希集合,我们可以在O(n)时间复杂度内解决问题,这比排序法更高效。掌握这种利用空间换时间的思路对解决类似问题很有帮助。

扩展思考

  1. 如果要求返回最长的连续序列本身而不仅仅是长度,该如何修改代码?
  2. 如何修改算法以处理包含重复数字的情况(虽然当前解法已经处理了)?
  3. 如果数字范围非常大但稀疏,如何进一步优化空间复杂度?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/93666.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/93666.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/93666.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

矿物分类系统开发笔记(一):数据预处理

目录 一、数据基础与预处理目标 二、具体预处理步骤及代码解析 2.1 数据加载与初步清洗 2.2 标签编码 2.3 缺失值处理 (1)删除含缺失值的样本 (2)按类别均值填充 (3)按类别中位数填充 (…

《UE5_C++多人TPS完整教程》学习笔记43 ——《P44 奔跑混合空间(Running Blending Space)》

本文为B站系列教学视频 《UE5_C多人TPS完整教程》 —— 《P44 奔跑混合空间(Running Blending Space)》 的学习笔记,该系列教学视频为计算机工程师、程序员、游戏开发者、作家(Engineer, Programmer, Game Developer, Author&…

TensorRT-LLM.V1.1.0rc1:Dockerfile.multi文件解读

一、TensorRT-LLM有三种安装方式,从简单到难 1.NGC上的预构建发布容器进行部署,见《tensorrt-llm0.20.0离线部署DeepSeek-R1-Distill-Qwen-32B》。 2.通过pip进行部署。 3.从源头构建再部署,《TensorRT-LLM.V1.1.0rc0:在无 GitHub 访问权限的服务器上编…

UniApp 实现pdf上传和预览

一、上传1、html<template><button click"takeFile">pdf上传</button> </template>2、JStakeFile() {// #ifdef H5// H5端使用input方式选择文件const input document.createElement(input);input.type file;input.accept .pdf;input.onc…

《用Proxy解构前端壁垒:跨框架状态共享库的从零到优之路》

一个项目中同时出现React的函数式组件、Vue的模板语法、Angular的依赖注入时,数据在不同框架体系间的流转便成了开发者不得不面对的难题—状态管理,这个本就复杂的命题,在跨框架场景下更显棘手。而Proxy,作为JavaScript语言赋予开发者的“元编程利器”,正为打破这道壁垒提…

MOESI FSM的全路径测试用例

MOESI FSM的全路径测试用例摘要&#xff1a;本文首先提供一个UVM版本的测试序列&#xff08;基于SystemVerilog和UVM框架&#xff09;&#xff0c;设计为覆盖MOESI FSM的全路径&#xff1b;其次详细解释如何使用覆盖组&#xff08;covergroup&#xff09;来量化测试的覆盖率&am…

git仓库和分支的关系

1️⃣ 仓库分支&#xff08;Repository Branch&#xff09;每个 Git 仓库都有自己的分支结构。分支决定你当前仓库看到的代码版本。示例&#xff1a;仓库分支只是局部修改&#xff0c;项目分支才是全局管理所有仓库分支的概念。wifi_camera 仓库&#xff1a; - main - dev - fe…

Linux的基本操作

Linux 系统基础操作完整指南一、文件与目录操作1. 导航与查看pwd (Print Working Directory)作用&#xff1a;显示当前所在目录的完整路径示例&#xff1a;pwd → 输出 /home/user/documents使用场景&#xff1a;当你在多层目录中迷失时快速定位当前位置ls (List)常用选项&…

npm设置了镜像 pnpm还需要设置镜像吗

npm配置镜像后是否需要为pnpm单独设置镜像&#xff1f; 是的&#xff0c;即使您已经为npm设置了镜像源&#xff08;如淘宝镜像&#xff09;&#xff0c;仍然需要单独为pnpm配置镜像源。这是因为npm和pnpm是两个独立的包管理工具&#xff0c;它们的配置系统和环境变量是分离的&a…

Linux管道

预备知识&#xff1a;进程通信进程需要某种协同&#xff0c;协同的前提条件是通信。有些数据是用来通知就绪的&#xff0c;有些是单纯的传输数据&#xff0c;还有一些是控制相关信息。进程具有独立性&#xff0c;所以通信的成本可能稍微高一点&#xff1b;进程间通信前提是让不…

基于Spring Boot的快递物流仓库管理系统 商品库存管理系统

&#x1f525;作者&#xff1a;it毕设实战小研&#x1f525; &#x1f496;简介&#xff1a;java、微信小程序、安卓&#xff1b;定制开发&#xff0c;远程调试 代码讲解&#xff0c;文档指导&#xff0c;ppt制作&#x1f496; 精彩专栏推荐订阅&#xff1a;在下方专栏&#x1…

脚手架开发-Common封装基础通用工具类<基础工具类>

书接上文 java一个脚手架搭建_redission java脚手架-CSDN博客 以微服务为基础搭建一套脚手架开始前的介绍-CSDN博客 脚手架开发-准备配置-进行数据初始化-配置文件的准备-CSDN博客 脚手架开发-准备配置-配置文件的准备项目的一些中间件-CSDN博客 脚手架开发-Nacos集成-CSD…

软件系统运维常见问题

系统部署常见问题 环境配置、兼容性问题。生产与测试环境的操作系统、库版本、中间件版本不一致&#xff0c;运行环境软件版本不匹配。新旧版本代码/依赖不兼容。依赖缺失或冲突问题。后端包启动失败&#xff0c;提示类/方法/第三方依赖库找不到或者版本冲突。配置错误。系统启…

2021 IEEE【论文精读】用GAN让音频隐写术骗过AI检测器 - 对抗深度学习的音频信息隐藏

使用GAN生成音频隐写术的隐写载体 本文为个人阅读GAN音频隐写论文&#xff0c;部分内容注解&#xff0c;由于原文篇幅较长这里就不再一一粘贴&#xff0c;仅对原文部分内容做注解&#xff0c;仅供参考详情参考原文链接 原文链接&#xff1a;https://ieeexplore.ieee.org/abstra…

PWA技术》》渐进式Web应用 Push API 和 WebSocket 、webworker 、serviceworker

PWA # 可离线 # 高性能 # 无需安装 # 原生体验Manifest {"name": "天气助手", // 应用全名"short_name": "天气", // 短名称&#xff08;主屏幕显示&#xff09;"start_url": "/index.html&…

数据结构——栈和队列oj练习

225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09; 这一题需要我们充分理解队列和栈的特点。 队列&#xff1a;队头出数据&#xff0c;队尾入数据。 栈&#xff1a;栈顶出数据和入数据。 我们可以用两个队列实现栈&#xff0c;在这过程中&#xff0c;我们总要保持其…

Java基础 8.19

目录 1.局部内部类的使用 总结 1.局部内部类的使用 说明&#xff1a;局部内部类是定义在外部类的局部位置&#xff0c;比如方法中&#xff0c;并且有类名可以直接访问外部类的所有成员&#xff0c;包含私有的不能添加访问修饰符&#xff0c;因为它的地位就是一个局部变量。局…

从父类到子类:C++ 继承的奇妙旅程(2)

前言&#xff1a;各位代码航海家&#xff0c;欢迎回到C继承宇宙&#xff01;上回我们解锁了继承的「基础装备包」&#xff0c;成功驯服了public、protected和花式成员隐藏术。但——⚠️前方高能预警&#xff1a; 继承世界的暗流涌动远不止于此&#xff01;今天我们将勇闯三大神…

【图像算法 - 16】庖丁解牛:基于YOLO12与OpenCV的车辆部件级实例分割实战(附完整代码)

庖丁解牛&#xff1a;基于YOLO12与OpenCV的车辆部件级实例分割实战&#xff08;附完整代码&#xff09; 摘要&#xff1a; 告别“只见整车不见细节”&#xff01;本文将带您深入实战&#xff0c;利用YOLO12-seg训练实例分割模型&#xff0c;结合OpenCV的强大图像处理能力&…

ubuntu22.04配置远程桌面

文章目录前言检查桌面类型xorg远程桌面(xrdp)安装xrdpxrdp添加到ssl-certwayland远程桌面(gnome-remote-desktop)检查安装开启开启状况检查自动登录奇技淫巧前言 在windows上使用远程桌面服务&#xff0c;连接ubuntu主机的远程桌面 检查桌面类型 查看桌面类型、协议 echo $…