128. 最长连续序列

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

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。128. 最长连续序列_第1张图片写在题前----

第一次做这个题的时候我的思路是暴力枚举,遍历整个数组若这个数不存在刚好比他小1的数则视为这个数是一个连续序列的起始点,然后在循环找数组中是否存在比这个数大1的数,依次进行查找并更新最大但时间复杂度达到惊人的O(N^{3})故放弃--重新找寻解决办法--故记录。

这道题目是关于 最长连续序列,给定一个无序的整数数组 nums,要求找到其中最长的连续元素序列,并返回其长度。为了高效解决这个问题,我们可以使用 哈希集合 来加速查找操作。

简单来说就是每个数都判断一次这个数是不是连续序列的开头那个数。----看完这个你应该基本了解思路了。

  • 怎么判断呢,就是用哈希表查找这个数前面一个数是否存在,即num-1在序列中是否存在。存在那这个数肯定不是开头,直接跳过。
  • 因此只需要对每个开头的数进行循环,直到这个序列不再连续,因此复杂度是O(n)。 以题解中的序列举例:
    [100,4,200,1,3,4,2]
    去重后的哈希序列为:
    [100,4,200,1,3,2]
    按照上面逻辑进行判断:
  1. 元素100是开头,因为没有99,且以100开头的序列长度为1
  2. 元素4不是开头,因为有3存在,过,
  3. 元素200是开头,因为没有199,且以200开头的序列长度为1
  4. 元素1是开头,因为没有0,且以1开头的序列长度为4,因为依次累加,2,3,4都存在。
  5. 元素3不是开头,因为2存在,过,
  6. 元素2不是开头,因为1存在,过。

解题思路:

    1. 去重

      • 由于题目要求的是连续的数字序列,并且如果数组中存在重复元素,我们只关心唯一的数字。所以,首先可以使用 unordered_set 来去重。
    2. 查找连续序列的开头

      • 对于每个数 e,我们只需要从 连续序列的开头 开始计算。如果 e - 1 存在于集合中,说明 e 是某个连续序列的中间或末尾,不需要计算。
      • 如果 e - 1 不存在于集合中,说明 e 是一个新的连续序列的起始点,接下来就可以开始计算以 e 开头的连续序列长度。
    3. 计算连续序列的长度

      • e 开始,不断检查 e + 1 是否在集合中存在,直到无法找到下一个连续的数字为止。
      • 每次找到一个新的连续数字,更新当前序列的长度。
    4. 更新结果

      • 在遍历过程中,记录遇到的最大连续序列长度。

    具体步骤:

    1. nums 中的所有元素插入到 unordered_set 中,去除重复元素。
    2. 遍历集合中的每个数字 e
      • 如果 e - 1 不在集合中,说明 e 是一个可能的连续序列的起始点。
      • e 开始,检查连续的数字 e + 1, e + 2, ... 是否在集合中,直到找不到为止,计算该连续序列的长度。
    3. 返回找到的最长连续序列的长度。

    代码实现:

    class Solution {
    public:
        int longestConsecutive(vector& nums) {
            unordered_set hash;
            for (auto e : nums) { // 集合去重
                hash.insert(e);
            }
            int ret = 0;
            for (auto e : hash) {
                if (!hash.contains(
                    e -
                    1)) { // 判断前一个数是否存在,存在则不需要计算这个,因为这个数不是连续序列的开头
                    int cur = e;
                    int curret = 1;
                    while (hash.contains(cur + 1)) { // 是开头--则计算长度
                        curret += 1;
                        cur += 1;
                    }
                    ret = max(ret, curret);
                }
                
            }
            return ret;
        }
    };

    时间复杂度:

    • 时间复杂度O(n),其中 n 是数组 nums 的长度。我们遍历一次数组将元素插入集合,然后对于每个元素,最多进行一次 while 循环来计算连续序列的长度。每个元素最多会被访问一次,因此总体复杂度是 O(n)
    • 空间复杂度O(n),我们使用了一个哈希集合来存储数组中的所有唯一元素,因此空间复杂度是 O(n)

    结论:

    这种方法通过哈希集合加速了查找操作,避免了对每个数字重复检查,从而提高了效率。

      你可能感兴趣的:(算法,数据结构)