C++零基础LeetCode热题100- 128.最长连续序列

embedded/2025/3/15 5:32:21/

128.最长连续序列

    • 题目描述
    • 思路
    • 步骤
    • 实现代码
    • 代码详解
    • 提交结果
    • 注意

题目描述

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

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
在这里插入图片描述

思路

       常规的思路可能是排序后遍历,找到最长的连续段。这样的话,时间复杂度是O(n log n),但题目要求O(n),所以这种方法不可行。
       那O(n)的算法就需要用哈希表了。

       可以先把所有数字存入一个哈希集合中,这样可以快速查询某个数是否存在。然后遍历数组中的每个数,对于每个数,如果它的前一个数(num-1)不在集合中,那么就以这个数为起点,开始向后查找连续的数,比如num+1、num+2等等,直到找不到为止。
       这样每个连续序列只会被处理一次,因为只有当当前数是序列的起点时才会进行遍历。

       例如,假设数组中有4,那么如果3存在的话,4就不是起点,所以不会被处理。只有当处理到1的时候,因为没有0存在,所以开始从1向上找,得到1、2、3、4,长度为4。这样可以确保每个元素最多被访问两次(一次是放入集合,另一次是在查找序列时),因此时间复杂度是O(n)。

步骤

  1. 将数组中的所有元素存入一个哈希集合,查询时间O(1)。

  2. 初始化最长长度max_length为0。

  3. 遍历数组中的每一个元素num:
    a. 如果num-1不在集合中,那么当前num可能是一个连续序列的起点。
    b. 然后从num开始,逐步检查num+1、num+2是否在集合中,直到找不到为止。
    c. 计算当前连续序列的长度,并更新max_length。

  4. 返回max_length。

每个元素最多被访问两次,所以总的时间复杂度是O(n)。

实现代码

class Solution {
public:int longestConsecutive(vector<int>& nums) {// 创建哈希集合,存储所有数字,用于O(1)时间复杂度的存在性检查unordered_set<int> num_set(nums.begin(), nums.end());int max_len = 0; // 记录最长连续序列的长度// 遍历数组中的每个数字for (int num : nums) {// 如果当前数字的前一个数不在集合中,说明当前数字可能是一个连续序列的起点if (num_set.find(num - 1) == num_set.end()) {int current_num = num; int current_len = 1;   // 当前连续序列的长度// 向后查找连续的数字,直到找不到下一个数为止while (num_set.find(current_num + 1) != num_set.end()) {current_num++; // 移动到下一个数字current_len++; // 增加当前序列长度}// 更新最大长度max_len = max(max_len, current_len);}}return max_len;
}
};

代码详解

1.unordered_set<int> num_set(nums.begin(), nums.end())将数组 nums 中的所有元素复制到一个哈希集合 num_set 中,用于快速构建一个哈希集合(HashSet)

   nums 是一个 vector<int> 数组
   nums.begin() 返回指向数组第一个元素的迭代器(指针)
   nums.end() 返回指向数组末尾(最后一个元素的下一个位置)的迭代器
   合起来表示将 nums 的全部元素作为输入范围。

unordered_set 的构造函数接受两个迭代器(beginend),将范围内的所有元素插入集合。
且插入时会自动去重:例如,如果 nums 中有多个 5,集合中只会保留一个 5。

有小白可能把unordered_setunordered_map弄混淆,前者是哈希集合,后者是哈希表。以下是区分:

容器用途模板参数示例适用场景
unordered_set<T>存储单一类型的元素,快速判断存在性unordered_set<int>只需判断元素是否存在
unordered_map<K,V>存储键值对,关联数据unordered_map<string, int>需要记录键的附加信息(如计数)

在本题中,unordered_set<int> 是最优选择,而 unordered_map<int, int> 既不必要,又浪费资源。

2.for (int num : nums)范围 for 循环,遍历容器(如数组、vector、list 等)中的每一个元素,可代替for (int i = 0; i < nums.size(); ++i)

   int num:定义一个临时变量 num,类型为 int(与容器元素类型一致)。
   nums:被遍历的容器(如 vector<int> 或数组)。
   循环过程:每次迭代时,将容器中的一个元素赋值给 num,并执行循环体内的代码。

3.if (num_set.find(num - 1) == num_set.end())

   end()unordered_set 的成员函数,返回指向集合末尾的迭代器(表示无效位置)
   如果 find() 返回的迭代器等于 end(),说明未找到 num - 1

提交结果

在这里插入图片描述

注意

1.for (int num : nums)范围 for 循环,可代替for (int i = 0; i < nums.size(); ++i)
范围 for 循环本质上是 语法糖,编译器会将其转换为传统的迭代器循环

2.外层循环的遍历对象一定要是哈希集合 num_set而不能是原数组nums,否则会出现:
在这里插入图片描述

原因:

当输入数组包含 大量重复元素 时,外层循环次数会远高于实际需要处理的元素数量。

例如:输入 nums = [0, 0, 0, 0, …](含无数个元素)。
哈希集合 num_set 中实际只有 1 个元素 0,外层循环仍会执行 1e5 次,但每次处理的逻辑相同,浪费大量时间。

因此:

情况外层循环次数时间复杂度适用场景
遍历原数组 numsO(n)O(n)无重复元素
遍历哈希集合 num_setO(m) (m ≤ n)O(n)存在大量重复元素

http://www.ppmy.cn/embedded/172409.html

相关文章

使用curl库编写爬虫程序的指令抓取优质视频

首先&#xff0c;curl本身是一个命令行工具&#xff0c;用来传输数据&#xff0c;支持多种协议&#xff0c;包括HTTP、HTTPS等。用户提到“使用curl库编写爬虫程序”&#xff0c;可能指的是用libcurl库在编程语言中调用&#xff0c;比如Python的pycurl&#xff0c;或者C/C直接使…

PHP前后开发纪录

一.LayUI相关 在LayUI中使用jquery读取本地json文件: // getJSON为直接读取本地文件&#xff0c;要改成调接口$.getJSON(/datafile/enviro-factory.json,function(data){data.forEach(element > {setMarkerLabel(element,T,map)});// setMarkerLabel(data[0],T,map)});二.p…

[Python爬虫系列]bilibili

[Python爬虫系列]bilibili 具体逻辑 bv号 -> 处理多P视频 -> 拿到cid -> sign -> 请求下载&#xff0c;其中sign参考前人算法&#xff08;https://github.com/SocialSisterYi/bilibili-API-collect&#xff09; b站视频下载链接 https://api.bilibili.com/x/pl…

EXCEL IF自动填充功能

使用Excel自动填充端口用途&#xff1a;提升工作效率的技巧 在日常工作中&#xff0c;Excel 是一个非常强大的工具&#xff0c;尤其是在处理大量数据时。通过使用 Excel 的自动填充功能&#xff0c;我们可以快速地为数据添加额外的信息&#xff0c;从而提升工作效率。本文将介…

Redis 6.2.7安装配置

Redis-6.2.7下载 下载地址&#xff1a;https://download.redis.io/releases/redis-6.2.7.tar.gz 解压缩文件 tar -zxvf redis-6.0.3.tar.gz 安装gcc yum install gcc 进入压缩包src目录下进行源码编译&#xff0c;将redis安装到/usr/local/redis目录下 cd /opt/software/red…

Flutter 基础组件 Image 详解

目录 1. 引言 2. 加载图片的方式 2.1 本地图片 2.2 网络图片 2.3 本地文件图片 2.4 内存图片 3. fit 参数&#xff1a;控制图片适应方式 4. 高级应用技巧 4.1 占位符与淡入效果 4.2 图片缓存管理 4.3 图片裁剪与滤镜 5. 性能优化指南 5.1 资源图片规范 2. 大图加…

手机遥控开关,是一种能让用户通过手机远程控制电器开关

移动管家手机遥控开关&#xff0c;是一种能让用户通过手机远程控制电器开关的智能设备。以YD238 - 6型为例&#xff0c;它可通过手机或座机远程控制&#xff0c;最大输出功率1100W&#xff0c;还可扩展大功率外挂接触器&#xff0c;具备来电、停电通知及记忆功能等&#xff0c;…

什么是全栈?

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点下班 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 &#x1f4c3;文章前言 &#x1f537;文章均为学习工…