主题
首先,本题是不能排序的,因为排序的时间复杂度是
核心思路:对于
为了做到
- 把
中的数都放入一个哈希集合中,这样可以 判断数字是否在 中。 - 如果
在哈希集合中,则不以 为起点。为什么?因为以 为起点计算出的序列长度,一定比以 为起点计算出的序列长度要长!这样可以避免大量重复计算。比如 ,从 开始,我们可以找到 这个连续序列;而从 开始,我们可以找到 这个连续序列,一定比从 开始的序列更长。
⚠注意:遍历元素的时候,要遍历哈希集合,而不是
python
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
st = set(nums) # 把 nums 转成哈希集合
ans = 0
for x in st: # 遍历哈希集合
if x - 1 in st: # 如果 x 不是序列的起点,直接跳过
continue
# x 是序列的起点
y = x + 1
while y in st: # 不断查找下一个数是否在哈希集合中
y += 1
# 循环结束后,y-1 是最后一个在哈希集合中的数
ans = max(ans, y - x) # 从 x 到 y-1 一共 y-x 个数
return anscpp
// C++ 版待补充cpp
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> st(nums.begin(), nums.end()); // 把 nums 转成哈希集合
int ans = 0;
for (int x : st) { // 遍历哈希集合
if (st.contains(x - 1)) { // 如果 x 不是序列的起点,直接跳过
continue;
}
// x 是序列的起点
int y = x + 1;
while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
y++;
}
// 循环结束后,y-1 是最后一个在哈希集合中的数
ans = max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
}
return ans;
}
};小优化:设
python
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
st = set(nums) # 把 nums 转成哈希集合
m = len(st)
ans = 0
for x in st: # 遍历哈希集合
if x - 1 in st: # 如果 x 不是序列的起点,直接跳过
continue
# x 是序列的起点
y = x + 1
while y in st: # 不断查找下一个数是否在哈希集合中
y += 1
# 循环结束后,y-1 是最后一个在哈希集合中的数
ans = max(ans, y - x) # 从 x 到 y-1 一共 y-x 个数
if ans * 2 >= m: # ans 不可能变得更大
break
return anscpp
// C++ 版待补充cpp
class Solution {
public:
int longestConsecutive(vector<int>& nums) {
unordered_set<int> st(nums.begin(), nums.end()); // 把 nums 转成哈希集合
int ans = 0;
for (int x : st) { // 遍历哈希集合
if (st.contains(x - 1)) { // 如果 x 不是序列的起点,直接跳过
continue;
}
// x 是序列的起点
int y = x + 1;
while (st.contains(y)) { // 不断查找下一个数是否在哈希集合中
y++;
}
// 循环结束后,y-1 是最后一个在哈希集合中的数
ans = max(ans, y - x); // 从 x 到 y-1 一共 y-x 个数
if (ans * 2 >= st.size()) {
break;
}
}
return ans;
}
};复杂度分析
- 时间复杂度:
,其中 是 的长度。在二重循环中,每个元素至多遍历两次:在外层循环中遍历一次,在内层循环中遍历一次。所以二重循环的时间复杂度是 的。比如 ,其中 不会进入内层循环,只有 会进入内层循环。 - 空间复杂度:
。其中 是 中的不同元素个数。
相似题目
分类题单
- 滑动窗口与双指针(定长/不定长/单序列/双序列/三指针/分组循环)
- 二分算法(二分答案/最小化最大值/最大化最小值/第K小)
- 单调栈(基础/矩形面积/贡献法/最小字典序)
- 网格图(DFS/BFS/综合应用)
- 位运算(基础/性质/拆位/试填/恒等式/思维)
- 图论算法(DFS/BFS/拓扑排序/基环树/最短路/最小生成树/网络流)
- 动态规划(入门/背包/划分/状态机/区间/状压/数位/数据结构优化/树形/博弈/概率期望)
- 常用数据结构(前缀和/差分/栈/队列/堆/字典树/并查集/树状数组/线段树)
- 数学算法(数论/组合/概率期望/博弈/计算几何/随机算法)
- 贪心与思维(基本贪心策略/反悔/区间/字典序/数学/思维/脑筋急转弯/构造)
- 链表、树与回溯(前后指针/快慢指针/DFS/BFS/直径/LCA)
- 字符串(KMP/Z函数/Manacher/字符串哈希/AC自动机/后缀数组/子序列自动机)
欢迎关注 B站@灵茶山艾府