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;
}
};