最长连续序列(哈希解)

128. 最长连续序列 - 力扣(LeetCode)

问题描述

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

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

样例输入

示例 1:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是
[1, 2, 3, 4]。它的长度为 4。

示例 2:

输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109

题解

如何判断连续序列

假如x是一个连续序列的起点,那么如果这个连续序列存在于nums中,那么只需要判断x,x+1,x+2,x+3,...,x+n都是否存在于nums中即可,如果这些数字都存在于nums中,那么n+1就是我们返回的结果

判断一个数是否存在于nums中,显然我们可以使用一个哈希表存储nums中的数,因为在哈希表中判断一个数是否存在的时间复杂度为O(1)

因此由上述思路,我们可以得到一个解法,枚举nums中每一个数x,判断x之后的x+1,x+2,x+3,...,x+n是否在哈希表中,最后返回结果即可。

但是还有一个问题是,如何判断我们遍历nums时枚举的数x是一个序列的起点呢?

判断枚举的数x是否是一个序列的起点

我们知道,如果一个数是nums中一个连续序列的起点数字,那么x-1,必然不存在于nums中,而我们已经使用了一个哈希表来存储nums中的所有数,因此我们只需要在枚举的时候判断x-1是否存在于哈希表中即可,如果x-1存在于哈希表中,那么该数就不是nums中连续序列的起点,跳过即可,否则就判断其后的数字是否存在,并返回结果

代码整体思路

故代码整体思路为:

  • 使用一个set存储nums中的所有数(使用set可以去重)
  • 遍历nums,判断nums[i]-1是否存在于set中
    • 如果num[i]-1存在与set中,说明nums[i]不是一个连续序列的起点,跳过
    • 否则说明num[i]是我们要找的某一个连续序列的起点,接下来判断nums[i]的每一个数是否存在于set中,也就是判断一个连续序列是否存在,并记录连续序列的长度
  • 更新最大连续序列的长度(因为每次找到的连续序列长度不一定是最大的,需要判断)

代码

class Solution {
public:
    int longestConsecutive(vector<int>& nums) {
        unordered_set<int> ms;
        //去重
        for(int num:nums)
            ms.insert(num);
        int res=0;
        for(int i=0;i<nums.size();i++)
        {
            //说明当前元素是一个连续序列的起始位置
            if(!ms.count(nums[i]-1))
            {
                int curNum=nums[i];
                int curSeq=1;//记录当前序列长度
                while(ms.count(curNum+1))//判断连续序列是否存在
                {
                    curNum++;
                    curSeq++;
                }
                res=max(res,curSeq);//更新最长序列长度
            }
        }
        return res;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值