最长连续序列
1、题目
给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。
请你设计并实现时间复杂度为 O(n) 的算法解决此问题。
示例 :
输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4。
2、解题思路
2.1理解题目要求
-
连续序列:[num,num+1,num+2,num+3,...]
-
找到最长的连续序列,并输出它的长度
-
序列开头:在数组中找不到当前num的上一个数(num-1)
用示例举例:在
nums = [100,4,200,1,3,2]中是序列开头的有"1","100","200",
2.2方法一整体思路架构
-
创建哈希集合
-
将数组中元素存储到哈希集合中(可以去除重复元素)
-
声明一个
SequenceLength接收最长序列的长度 -
遍历哈希集合,声明两个变量
currentNum(当前数字),currentlength(当前长度) -
判断当前值
num是否是序列开头,(作为序列开头,当前值num前面就不会有num-1) -
如果当前值
num不是序列开头,那就直接跳过。如果当前值num为序列开头,当有num+1存在时,当前长度加一。将当前长度与最长长度比较,更新最长序列长度 -
最后返回比较后的最长序列长度
class Num { public int longestConsecutive(int[] nums) { // 创建一个 HashSet 集合用于存储数组中的整数 Set<Integer> NumSet = new HashSet<Integer>(); for (int num : nums) { // 将数组中的每个整数添加到集合中,去除重复元素 NumSet.add(num); } int SequenceLength = 0; for (int num : NumSet) { int currentNum = num; int currentlength = 1; // 如果集合中不包含当前整数减一的值,说明当前整数可能是一个连续序列的起点 if (!NumSet.contains(num - 1)) { // 当集合中包含当前数字加一的值时,说明连续序列可以继续延伸 while (NumSet.contains(currentNum + 1)) { currentNum += 1; currentlength += 1; } // 更新最长连续序列的长度 SequenceLength = Math.max(SequenceLength, currentlength); } //存在那这个数肯定不是开头,直接跳过。 } return SequenceLength; }
2.3方法二整体思路架构
- 创建哈希表,初始的 key值和value值都为当前num值
- 循环数组,判断当前值
num是否是序列开头,(作为序列开头,当前值num前面就不会有num-1) - 如果当前值
num不是序列开头,那就直接跳过。如果当前值num为序列开头,当有num+1存在时,将num+1传给bignum,最后将bignum存到哈希表中key值为num的value中, - 最后找到的序列长度就是bignum - num +1(num为序列开头,bignum为序列结尾)
class Num {
public int longestConsecutive(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
for (int num : nums) {
map.put(num, num);
}
int SequenceLength = 0;
for (int num : nums) {
int bignum = map.get(num);
if (!map.containsKey(num - 1)) {
while (map.containsKey(bignum + 1)) {
bignum = map.get(bignum + 1);
}
map.put(num, bignum);
SequenceLength = Math.max(SequenceLength, bignum - num + 1);
}
}
return SequenceLength;
}