目录
[示例 1](#示例 1)
[示例 2](#示例 2)
[解法一:HashSet 版](#解法一:HashSet 版)
[解法二:HashMap 版](#解法二:HashMap 版)
问题描述
给定一个未排序的整数数组 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
提示
0 <= nums.length <= 10^5
-10^9 <= nums[i] <= 10^9
过题图片

解法一:HashSet 版
思路
利用 HashSet 存储数组中的元素,然后遍历数组,对于每个元素,检查其前后元素是否存在于 HashSet 中,以此来确定连续序列的长度。
步骤
-
初始化 :定义一个
HashSet
来存储数组中的所有元素,以及两个变量max
用来记录最长连续序列的长度,sum
用来记录当前连续序列的长度。 -
填充 HashSet :遍历数组
nums
,将所有元素添加到HashSet
中。 -
寻找连续序列 :再次遍历数组
nums
,对于每个元素num
:- 如果
num - 1
存在于HashSet
中,说明num
不是连续序列的起点,继续下一个循环。 - 如果
num - 1
不存在于HashSet
中,那么num
是一个连续序列的起点,将sum
设置为 1(当前序列的长度)。 - 检查
num + 1
是否存在于HashSet
中,如果存在,则增加sum
,直到不存在为止,表示连续序列结束。 - 更新
max
为sum
和max
中的较大值。
- 如果
-
返回结果 :遍历结束后,
max
即为所求的最长连续序列的长度。
代码实现
java
class Solution {
public int longestConsecutive(int[] nums) {
int sum = 1;
int max = 0;
Arrays.sort(nums);
Set<Integer> set = new HashSet<>();
for (int num : nums) {
if (set.contains(num)){
continue;
}
else if (set.contains(num - 1)) {
sum++;
} else {
sum = 1;
}
max = Math.max(max, sum);
set.add(num);
}
return max;
}
}
解法二:HashMap 版
思路
首先对数组进行排序,然后使用 HashMap 来存储每个数字和其连续序列的列表。对于每个数字,如果它不是当前连续序列的下一个数字,则开始一个新的连续序列。最后,遍历 HashMap 来找到最长的连续序列。
步骤
-
初始化 :定义一个
HashMap
来存储每个数字及其连续序列的列表,以及一个变量max
用来记录最长连续序列的长度。 -
排序数组 :对数组
nums
进行排序。 -
构建连续序列 :遍历排序后的数组
nums
,对于每个元素num
:- 如果
num
不等于num - 1
(即num
不是重复的),则以num
为起点开始构建一个新的连续序列。 - 如果
num
等于num - 1
+ 1,则将num
添加到前一个数字的连续序列中。 - 如果
num
不等于num - 1
且不等于num + 1
- 1,则num
是一个新的连续序列的起点,创建一个新的列表并添加到HashMap
中。
- 如果
-
寻找最长连续序列 :遍历
HashMap
中的所有值(即所有连续序列的列表),更新max
为当前序列长度和max
中的较大值。 -
返回结果 :遍历结束后,
max
即为所求的最长连续序列的长度。
代码实现
java
class Solution {
public int longestConsecutive(int[] nums) {
HashMap<Integer,List<Integer>> map = new HashMap<>();
Arrays.sort(nums);
int j=0;
for(int i=0;i<nums.length;i++){
List<Integer> list = map.getOrDefault(nums[j], new ArrayList<Integer>());
if(i==0)
list.add(nums[i]);
else if(nums[i]==nums[i-1]+1)
list.add(nums[i]);
else if(nums[i]!=nums[i-1]){
j=i;
System.out.println(j);
List<Integer> list1 = map.getOrDefault(nums[j], new ArrayList<Integer>());
list1.add(nums[j]);
map.put(nums[j],list1);
continue;
}
map.put(nums[j],list);
}
int max=0;
for (List<Integer> num : map.values()) {
max = Math.max(max, num.size());
}
System.out.println(map);
return max;
}
}
题目链接
总结
两种解法都利用了 HashSet 或 HashMap 来减少查找的时间复杂度,使得整体的时间复杂度为 O(n)。HashSet 版的解法更为简洁,而 HashMap 版的解法则提供了一种不同的思路。