LeetCode Hot100【哈希-128.最长连续序列】

打印 上一主题 下一主题

主题 1721|帖子 1721|积分 5163

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
标题:128. 最长连续序列

  1. class Solution {
  2. public:
  3.     int longestConsecutive(vector<int>& nums) {
  4.         unordered_set<int> num_set;  // 使用哈希集合存储数组元素
  5.         for (const int& num : nums) {
  6.             num_set.insert(num);  // 插入数组中的每个数
  7.         }
  8.         int longestStreak = 0;  // 记录最长连续序列的长度
  9.         for (const int& num : num_set) {
  10.             // 如果 num - 1 不在集合中,则 num 是序列的起点
  11.             if (!num_set.count(num - 1))
  12. {
  13.                 int currentNum = num;
  14.                 int currentStreak = 1;
  15.                 // 检查是否存在 num + 1, num + 2, ..., 形成连续序列
  16.                 while (num_set.count(currentNum + 1)) {
  17.                     currentNum += 1;
  18.                     currentStreak += 1;
  19.                 }
  20.                 // 记录最大长度
  21.                 longestStreak = max(longestStreak, currentStreak);
  22.             }
  23.         }
  24.         return longestStreak;
  25.     }
  26. };
复制代码
实行流程

  1. nums = {100, 4, 200, 1, 3, 2}
  2. ;
复制代码
实行步调如下:

步调 1:构建 unordered_set

哈希集合 num_set 存储:
  1. {100, 4, 200, 1, 3, 2}
复制代码
步调 2:遍历 num_set 并计算最长连续序列

遍历元素



  • num = 100
    - num - 1 = 99 不在 num_set,但 num + 1 = 101 也不在。
    - currentStreak = 1,最长序列长度更新为 1。
  • num = 4
    - num - 1 = 3 在 num_set,跳过(4 不是起点)。
  • num = 200
    - num - 1 = 199 不在 num_set,但 num + 1 = 201 也不在。
    - currentStreak = 1,最长序列长度仍为 1。
  • num = 1
    - num - 1 = 0 不在 num_set,1 是序列起点。
    - 计算连续序列 1 → 2 → 3 → 4,currentStreak = 4。
    - longestStreak = max(1, 4) = 4。
    最终返回 longestStreak = 4。
时间 & 空间复杂度

操作时间复杂度空间复杂度插入 unordered_setO(n)O(n)遍历 unordered_setO(n)O(1)查询 unordered_set.count()O(1)O(1) 最终


  • 时间复杂度:O(n)(每个元素最多访问两次)。
  • 空间复杂度:O(n)(存储 unordered_set)。
关键点解析


  • 哈希表加速查找:传统暴力解法是 双重循环(O(n²)),利用 unordered_map 将查找优化到 O(1) 。
  • 边查找边插入:包管不会取到相同元素的索引,比方 [3, 3] 这样的情况。
优化 & 变种

假如 nums 颠末 排序,可以利用 O(n log n) 的解法:
  1. int longestConsecutive(vector<int>& nums) {
  2.     if (nums.empty()) return 0;
  3.     sort(nums.begin(), nums.end());
  4.     int longest = 1, current = 1;
  5.     for (int i = 1; i < nums.size(); i++) {
  6.         if (nums[i] == nums[i - 1]) continue;  // 跳过重复项
  7.         if (nums[i] == nums[i - 1] + 1) {
  8.             current += 1;
  9.         } else {
  10.             longest = max(longest, current);
  11.             current = 1;
  12.         }
  13.     }
  14.     return max(longest, current);
  15. }
复制代码
但 哈希表解法更优,因为 无需排序,时间复杂度更低(O(n))。

基础知识

1. unordered_set<int>

  1. unordered_set<int> num_set;
复制代码


  • C++ STL 提供的哈希集合,底层基于哈希表,查询平均复杂度为 O(1)。
  • 去重特性:集合中不能有重复元素。
基本操作
  1. unordered_set<int> s;
  2. s.insert(10);
  3. s.count(10); // 返回 1,表示存在
  4. s.count(5);  // 返回 0,表示不存在
复制代码
2. for (const int& num : num_set)

  1. for (const int& num : num_set) { ... }
复制代码


  • 基于范围的 for 遍历,避免利用索引。
  • 利用 const int& num 避免拷贝,进步性能。
3. num_set.count(num - 1)

  1. if (!num_set.count(num - 1))
复制代码


  • count(x) 查抄集合中是否有 x,返回 1 或 0。
  • 假如 num - 1 不存在,则 num 是一个新的连续序列的起点。
4. while (num_set.count(currentNum + 1))

  1. while (num_set.count(currentNum + 1)) {
  2.     currentNum += 1;
  3.     currentStreak += 1;
  4. }
复制代码


  • 不断查抄 num + 1 是否存在,直到连续序列断开。
示例
  1. unordered_set<int> s = {1, 2, 3, 4};
  2. int num = 1, streak = 1;
  3. while (s.count(num + 1)) {
  4.     num += 1;   // num 变成 2, 3, 4
  5.     streak += 1; // streak 变成 2, 3, 4
  6. }
复制代码
最终 streak = 4。
5. max(longestStreak, currentStreak)

  1. longestStreak = max(longestStreak, currentStreak);
复制代码


  • 取最大值,确保 longestStreak 存储最长的连续序列。
总结

C++语法作用unordered_set哈希集合(去重 & 快速查询)for (const int& num : num_set)遍历哈希表count(x)查抄集合是否包罗 xwhile (num_set.count(currentNum + 1))查找连续元素max(a, b)取最大值
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

涛声依旧在

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表