LeetCodeHot100-128-最长连续序列

题目

给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例 1:

1
2
3
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4

示例 2:

1
2
输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

提示:

  • 0 <= nums.length <= 105
  • -109 <= nums[i] <= 109

题解

Python

法一:哈希表

思路

先把 nums 转为哈希集合(set),也就是说,我们要把原先会存在重复数据的列表变成无重复数据的集合,再遍历集合,如果 x - 1 存在集合中,说明 x 不是一个连续序列的起点,就跳过当前数据,继续往后找。如果 x 是序列起点,用 y = x + 1 表示其后续的一个元素,如果 y 在集合里,y 自增,然后继续看 y 是否在集合里,直到退出循环。

结果 ans 就为 ans 和 y - x (表示序列长度)的最大值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
ans = 0
st = set(nums) # 把 nums 转成哈希集合
for x in st:
if x - 1 in st:
continue
# x 是序列的起点
y = x + 1
while y in st: # 不断查找下一个数是否在哈希集合中
y += 1
# 循环结束后,y-1 是最后一个在哈希集合中的数
ans = max(ans, y - x) # 从 x 到 y-1 一共 y-x 个数
return ans

法二:排序

思路

朴素解法:排序后查找连续序列

解题过程

先对序列进行排序,然后进行一次遍历,遍历时进行以下判断:

  1. 如果当前 index 默认为 0,说明是第一个数,默认要 + 1;
  2. 如果当前位置的数,比前一个数刚好大 1,当前最长连续序列 temp + 1;
  3. 如果当前位置的数和前一个数一样大,那么继续遍历;
  4. 如果当前位置的数 > 前一个数 + 1,更新结果 res ,重置 temp 。
  5. 最后需要注意,可能整个数组都是连续的,返回的结果再使用 max() 返回最大的序列长度。

复杂度

  • 时间复杂度: O(n)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
# 朴素解法:对数组进行排序,再进行连续性判断
if len(nums) == 0:
return 0
sorted_nums = sorted(nums)
# 默认为 1,因为当前数字也需要包含在内
res = -float('inf')
temp = 0
for index, num in enumerate(sorted_nums):
# 后方 = 当前 + 1, 计数 + 1,继续遍历
if index == 0 or sorted_nums[index] == sorted_nums[index - 1] + 1:
temp += 1
elif sorted_nums[index] == sorted_nums[index - 1]:
continue
# 否则重新计数
else:
if res < temp:
res = temp
temp = 1
# 考虑全部都是连续的情况,res没有被赋值
return max(res, temp)
运行结果

Java

我的本题解法应该是纯基于数组来做的,时间复杂度击败98.52%,空间复杂度击败90.44%,算是比较不错的解法了。

最基本的思想就是先排序,然后我们再找最长的连续序列。

算法步骤:

  1. 排序

  2. 初始化结果res和每轮的最大长度tempMax

  3. 从下标0到倒数第二个数开始,遍历nums数组:

    • 如果数字相同了,我们继续下一轮遍历;

    • 如果下一个数字比当前数字大1tempMax++

    • 如果下一个数字不连续了,更新res,初始化tempMax

  4. 注意最后一个数字没有进行比较,这里需要将最后一个数字如果连续或者相等(防止后面好几个数字一直都是连续的情况),tempMax++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
public int longestConsecutive(int[] nums) {
// 可以先排序后再找最长的连续序列
if (nums.length == 0) {
return 0;
} else if (nums.length == 1) {
return 1;
}
Arrays.sort(nums);
int res = Integer.MIN_VALUE, tempMax = 0;
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i + 1] == nums[i]) {
continue;
} else if (nums[i + 1] == nums[i] + 1) {
tempMax++;
} else {
res = Math.max(tempMax + 1, res);
tempMax = 0;
}
}
if (nums[nums.length - 1] == nums[nums.length - 1 - 1] + 1
|| nums[nums.length - 1] == nums[nums.length - 1 - 1]) {
tempMax++;
}
res = Math.max(tempMax, res);
return res;
}
}

LeetCodeHot100-128-最长连续序列
https://excelius.xyz/leetcodehot100-128-最长连续序列/
作者
Excelius
发布于
2024年12月28日
许可协议