力扣-128-最长连续序列
自主思考
需要判定连续并计数
需要排序吗?那么又怎么判断是连续的数字呢
这里的排序可以用插入到set替代?
评论区直接用sort()函数,还很快
指定一个数,然后将他的后一个数与它++后做对比
- 如果一致就认为是连续的,并且计数器加一
- 如果不一致就直接跳过
指针后移
能不能统一这两步呢?每排一个数字就将它与前一个数字++做对比
- 如果相同则计数器加一
- 如果不同,则在当前计数器值与最大值中取大值,并清空计数器
那么哪一个排序算法能够统一这个过程呢?
选择排序吗,但是效率很低
主要时间应该是花在每次找出最小值上面,也就是说时间效率O(N2)
选择排序的优化…?
官方题解
哈希表
实现
第一遍,跟着敲写注释
这个题解中使用hashset很方便地解决了检索序列中是否存在某一元素的问题
看起来其实代码很简单,时间复杂度时O(N)
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
// 为什么他这里使用了hashset
// 后面检索是否存在元素更方便
unordered_set<int> num_set;
// 将数组中的数字插入到hashset中
// 但是这里没排序
for (const int& num : nums) {
num_set.emplace(num);
}
// 用于保存最大连续子数组长度
int longestStreak = 0;
// 遍历序列中的每一个元素
for (const int& num : num_set) {
if (!num_set.count(num - 1)) {
// 当数字的前一个连续值不存在时,
// 如果存在了,那么从当前数字开始的连续序列肯定是被包含了的
int currentNum = num;
int currentStreak = 1;
while (num_set.count(currentNum+1))
{
currentNum += 1;
currentStreak += 1;
}
longestStreak = max(longestStreak, currentStreak);
// 评论区看到的剪枝,原理是当最大序列长度已经超过一半时,后面的元素就不需要
遍历了,不可能更长了
if (longestStreak >= nums.size() / 2 + 1) break;
}
}
return longestStreak;
}
这题其实还有很多其他的解法