1、题目来源
2、题目描述
给定一个未排序的整数数组 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 <= 105
-109 <= nums[i] <= 109
3、题解分析
方法一:哈希+枚举
class Solution {
public int longestConsecutive(int[] nums) {
// 思路:枚举匹配,即以每个数为起点枚举
// 先用哈希去重
HashSet<Integer> nums_set = new HashSet<>();
for(int num:nums){
nums_set.add(num);
}
int ans = 0;// 记录答案
for(int num:nums_set){
// 减枝:如果存在num-1,就跳过,因为肯定会从num-1开始枚举,并且答案会比从num开始枚举更长
if(nums_set.contains(num - 1)){
continue;
}
int curNum = num;
int curLen = 1;
// 枚举
while(nums_set.contains(curNum + 1)){
++curLen;
++curNum;
}
ans = Math.max(ans,curLen);
}
return ans;
}
}
方法二:哈希存储区间端点的值
class Solution {
public int longestConsecutive(int[] nums) {
// 思路:使用哈希表存储每个端点值对应的连续区间的长度
int ans = 0;
Map<Integer,Integer> hash = new HashMap<>();
for(int num: nums){
// 只处理新数
if(!hash.containsKey(num)){
// 找出左边相邻数的连续区间,若无则为0
int lenL = hash.getOrDefault(num - 1,0);
// 找出右边相邻数的连续区间,若无则为0
int lenR = hash.getOrDefault(num + 1,0);
// 得到新的连续区间的长度
int len = lenL + 1 + lenR;
// 更新左右端点的连续区间长度
if(lenL != 0){
hash.put(num-lenL,len);
}
if(lenR != 0){
hash.put(num+lenR,len);
}
// 当num为区间端点时,该hash值会使用到
hash.put(num,len);
ans = Math.max(ans,len);
}
}
return ans;
}
}