128.最长连续序列

要再O(n)时间复杂度内找到最长连续数字序列,核心思路是:

1、先用哈希集合unordered_set存储数组所有元素,利用集合的O(1)查找特性;直接在原数组中查找元素的时间复杂度是 O(n),而哈希集合(unordered_set)的查找时间复杂度是 O(1)(平均情况)。这一点点差异,会让整个算法的时间复杂度发生质的变化。
2、遍历每个元素(for循环),仅当该元素是连续序列的起点(即当num-1不在集合中)时(if条件判断),才向后查找连续数组(while循环),统计序列长度;
3、全程记录最长序列的长度

这种方式能保证每个元素最多被访问2次(一次遍历,一次作为连续序列被查找)整体时间复杂度为O(n)。

完整代码实现:
#include
#include
#include <unordered_set>
using namespace std;

int longestConsecutive(vector& nums) {

// 1. 将数组元素存入无序集合,去重且支持O(1)查找
unordered_set<int> num_set(nums.begin(), nums.end());
int max_length = 0; // 记录最长连续序列长度

// 2. 遍历集合中的每个元素
for (int num : num_set) {
    // 仅当num是连续序列的起点(num-1不存在)时,才开始统计
    if (num_set.find(num - 1) == num_set.end()) {
        int current_num = num;
        int current_length = 1; // 当前连续序列长度

        // 3. 向后查找连续数字,统计长度
        while (num_set.find(current_num + 1) != num_set.end()) {
            current_num++;
            current_length++;
        }

        // 4. 更新最长长度
        max_length = max(max_length, current_length);
    }
}

return max_length;

}

// 测试用例

int main() {

// 示例1:常规情况
vector<int> nums1 = {100, 4, 200, 1, 3, 2};
cout << "最长连续序列长度:" << longestConsecutive(nums1) << endl; // 输出4(序列1,2,3,4)

// 示例2:空数组
vector<int> nums2 = {};
cout << "最长连续序列长度:" << longestConsecutive(nums2) << endl; // 输出0

// 示例3:单元素数组
vector<int> nums3 = {5};
cout << "最长连续序列长度:" << longestConsecutive(nums3) << endl; // 输出1

// 示例4:重复元素+连续序列
vector<int> nums4 = {0, 3, 7, 2, 5, 8, 4, 6, 0, 1};
cout << "最长连续序列长度:" << longestConsecutive(nums4) << endl; // 输出9(0-8)

return 0;

}

代码关键部分解释
1、哈希集合初始化:unordered_set num_set(nums.begin(), nums.end())
将数组元素存入集合自动去重,且后续查找操作的时间复杂度为 O (1)。
2、判断序列起点:if (num_set.find(num - 1) == num_set.end())
只有当 num-1 不在集合中时,num 才是连续序列的第一个元素,避免重复统计(比如遍历到 2 时,若 1 存在,就不需要再从 2 开始统计,因为从 1 开始已经统计过了)。

具体代码解释
if (num_set.find(num - 1) == num_set.end())

代码片段 含义
num_set 存储数组所有元素的哈希集合(unordered_set)
num_set.find(num - 1) 在集合中查找 num-1 这个数字:- 如果找到,返回指向该元素的迭代器;- 如果没找到,返回 num_set.end()(集合的 “末尾” 迭代器,代表 “没找到”)
== num_set.end() 判断 “查找结果” 是否等于 “末尾迭代器”,即:是否没找到 num-1

unordered_set num_set(nums.begin(), nums.end());

部分 含义
unordered_set 声明一个存储 int 类型元素的无序哈希集合(STL 容器);unordered_set 是 C++ STL 提供的哈希集合容器,底层基于哈希表实现。
num_set 你定义的这个哈希集合的变量名。
(nums.begin(), nums.end()) 传给 unordered_set 构造函数的参数,是一对 “迭代器”:- nums.begin():指向数组 nums 第一个元素的迭代器;- nums.end():指向数组 nums 最后一个元素下一个位置的迭代器;这对迭代器共同表示 “数组 nums 的所有元素范围”。

核心原理范围构造函数
unordered_set 提供了多种构造函数,这里用到的是范围构造函数(Range Constructor),其作用是:
遍历传入的迭代器范围([begin, end)),把范围内的所有元素依次插入到 unordered_set 中,同时自动去重(因为集合不允许重复元素)

num_set(unordered_set)能自动去重,核心原因是:集合(Set)这种数据结构的本质特性 —— 不允许存储重复元素,这是 C++ STL 中 unordered_set 的设计规则,和底层实现逻辑紧密相关

posted @ 2026-03-23 15:33  AlexXuu  阅读(14)  评论(0)    收藏  举报