题目
给定一个未排序的整数数组 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示例 3:
输入:nums = [1,0,1,2] 输出:3
分析
枚举每个数去匹配
是否存在会达到O(
),不符合题意。因此需要注意避免重复枚举,即起点数
一定是在数组中不存在
的,因此每次在哈希表中检查是否存在
即能判断是否需要跳过。
哈希表法
时间复杂度:O()
空间复杂度:O()
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if (nums.empty()) return 0;
unordered_set<int> numSet(nums.begin(), nums.end());
int res = 0;
for (int num : numSet) {
// 如果 num-1 不在集合中,说明 num 是序列的起点
if (!numSet.count(num - 1)) {
int currentNum = num;
int currentStreak = 1;
// 向右扩展序列
while (numSet.count(currentNum + 1)) {
currentNum++;
currentStreak++;
}
// 更新最长连续序列
res = max(res, currentStreak);
}
}
return res;
}
};
count
替代 find 效率更高
知识充电
unordered_set
是 C++ 标准库中提供的一种容器,用于存储唯一的元素,无序存储。它的底层实现通常基于哈希表,因此查找、插入和删除操作的平均时间复杂度为 O(1),但在最坏情况下可能会退化为 O(n),取决于哈希冲突的数量。
插入元素
insert()
std::unordered_set<int> s; // 创建一个空的 unordered_set
auto result = s.insert(7);
if (result.second) {
std::cout << "插入成功\n";
} else {
std::cout << "元素已存在\n";
}
emplace()
s.emplace(50);
查找元素
find()
auto it = s.find(3);
if (it != s.end()) {
std::cout << "找到了元素: " << *it << std::endl;
} else {
std::cout << "元素不存在\n";
}
删除元素
erase()
s.erase(4); // 删除元素 4
auto it = s.find(5);
if (it != s.end()) {
s.erase(it); // 使用迭代器删除元素 5
}
clear()
s.clear(); // 清空所有元素
检查键个数
count()
if (s.count(3)) {
std::cout << "元素 3 存在\n";
} else {
std::cout << "元素 3 不存在\n";
}
检查容器状态
empty()
if (s.empty()) {
std::cout << "集合为空\n";
} else {
std::cout << "集合不为空\n";
}
size()——返回元素数量
遍历元素
for (auto it = s.begin(); it != s.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用范围基 for 循环
for (const auto& elem : s) {
std::cout << elem << " ";
}
std::cout << std::endl;