力扣-128-最长连续序列

自主思考

需要判定连续并计数

需要排序吗?那么又怎么判断是连续的数字呢

这里的排序可以用插入到set替代?
评论区直接用sort()函数,还很快

指定一个数,然后将他的后一个数与它++后做对比

  1. 如果一致就认为是连续的,并且计数器加一
  2. 如果不一致就直接跳过
    指针后移

能不能统一这两步呢?每排一个数字就将它与前一个数字++做对比

  1. 如果相同则计数器加一
  2. 如果不同,则在当前计数器值与最大值中取大值,并清空计数器

那么哪一个排序算法能够统一这个过程呢?
选择排序吗,但是效率很低
主要时间应该是花在每次找出最小值上面,也就是说时间效率O(N2)
选择排序的优化…?

官方题解

哈希表

实现

第一遍,跟着敲写注释

这个题解中使用hashset很方便地解决了检索序列中是否存在某一元素的问题
看起来其实代码很简单,时间复杂度时O(N)

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        // 为什么他这里使用了hashset
        // 后面检索是否存在元素更方便
        unordered_set<int> num_set;
        // 将数组中的数字插入到hashset中
        // 但是这里没排序
        for (const int& num : nums) {
            num_set.emplace(num);
        }

        // 用于保存最大连续子数组长度
        int longestStreak = 0;

        // 遍历序列中的每一个元素
        for (const int& num : num_set) {
            if (!num_set.count(num - 1)) {
                // 当数字的前一个连续值不存在时,
                // 如果存在了,那么从当前数字开始的连续序列肯定是被包含了的
                int currentNum = num;
                int currentStreak = 1;

                while (num_set.count(currentNum+1))
                {
                    currentNum += 1;
                    currentStreak += 1;
                }
                longestStreak = max(longestStreak, currentStreak);
                // 评论区看到的剪枝,原理是当最大序列长度已经超过一半时,后面的元素就不需要 
                   遍历了,不可能更长了
                if (longestStreak >= nums.size() / 2 + 1) break;
            }
        }
        return longestStreak;
    }

这题其实还有很多其他的解法

posted @ 2022-07-14 15:07  YaosGHC  阅读(43)  评论(0)    收藏  举报