leetcode-128.最长连续序列

哈希表

哈希表,又称散列表,使用 O(n) 空间复杂度存储数据,通过哈希函数映射位置,从而实现近似 O(1) 时间复杂度的插入、查找、删除等操作。

C++ 中的哈希集合为 unordered_set,可以查找元素是否在集合中。如果需要同时存储键和值,则需要用 unordered_map,可以用来统计频率,记录内容等等。

如果元素有穷,并且范围不大,那么可以用一个固定大小的数组来存储或统计元素。例如我们需要统计一个字符串中所有字母的出现次数,则可以用一个长度为 26 的数组来进行统计,其哈希函数即为字母在字母表的
位置,这样空间复杂度就可以降低为常数。

如果需要大小关系的维持,且插入查找并不过于频繁,则可以使用有序的 set/map 来代替unordered_set/unordered_map。


题目详情

给定一个未排序的整数数组 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

因为题目要求复杂度为 O(n) 的算法,显然是不让我们暴力求解,我们可以利用hash:

把所有数字放到一个哈希表,然后不断地从哈希表中任意取一个值,并删除掉其之前之后的所有连续数字,然后更新目前的最长连续序列长度。
重复这一过程,我们就可以找到所有的连续数字序列。

我的代码:

class Solution 
{
public:
    int longestConsecutive(vector<int>& nums) 
    {
        unordered_set<int> hash;
        for (const int &num : nums) //将数组存入hash
        {
            hash.insert(num);
        }
        int ans = 0;
        while (!hash.empty())
        {
            int cur = *(hash.begin()); //从第一个数字开始
            hash.erase(cur);           //将这个数字出表
            int next = cur + 1, prev = cur - 1; //寻找该数字的前后
            while (hash.count(next))   //持续找后面的数字next并count
            {
                hash.erase(next++);
            }
            while (hash.count(prev))  //持续找前面的数字prev并count
            {
                hash.erase(prev--);
            }
            ans = max(ans, next - prev - 1); //每次找完一串序列就尝试更新ans
        }
        return ans;
    }
};
posted @ 2022-09-07 09:23  ggaoda  阅读(6)  评论(0编辑  收藏  举报  来源