数组中的最长连续序列
数组中的最长连续序列
题目:数组中的最长连续子序列
《程序员代码面试指南》第75题 P248 难度:尉★★☆☆
这题我一上来想到先排序再找最长序列,不过就算使用最快的排序算法,时间复杂度也达到了O(NlogN),不符合题目要求的O(N)。
介绍两种解法:
首先是书中使用哈希表的解法:
- 生成哈希表map,key代表遍历过的某个数,value代表key这个数所在的最长连续序列的长度。同时map还可以表示arr中的一个数之前是否出现过。
- 从左到右遍历arr。如果arr[i]之前出现过,直接遍历下一个数。如果arr[i]没出现过,首先在map中加入记录(arr[i],1),代表目前arr[i]单独作为一个连续序列。然后看map中是否含有arr[i]-1,如果有,利用map得到该序列的长度,记为lenA,最小值leftA,最大值rightA,只在map中更新与leftA和rightA有关的记录,更新成(leftA,lenA)和(rightA,lenA)。对于arr[i]+1亦然,更新成(leftB,lenB)和(rightB,lenB)。
- 遍历过程中用全局变量max记录每次合并出的序列的长度最大值,最后返回max。
整个过程中,只是每个连续序列最小值和最大值在map中的记录有意义,中间数的记录不会再更新,因为再也不会用到。如果一个没出现的数能够把某个连续区间扩大,或把某两个连续区间连在一起,只需要map中有关这个连续区间最小值和最大值的记录。
public int longestConsecutive(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;
}
int max = 1;
HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();
for (int i = 0; i < arr.length; i++) {
if (!map.containsKey(arr[i])) {
map.put(arr[i], 1);
if (map.containsKey(arr[i] - 1)) {
max = Math.max(max, merge(map, arr[i] - 1, arr[i]));
}
if (map.containsKey(arr[i] + 1)) {
max = Math.max(max, merge(map, arr[i], arr[i] + 1));
}
}
}
return max;
}
public int merge(HashMap<Integer, Integer> map, int less, int more) {
int left = less - map.get(less) + 1;
int right = more + map.get(more) - 1;
int len = right - left + 1;
map.put(left, len);
map.put(right, len);
return len;
}
力扣解法:
首先将原数组放入HashSet中去重,然后对于每个数x,如果在set中存在前驱数x-1,则直接跳过。如果不存在,则不断尝试匹配x+1,x+2,……是否存在,得到最长序列x,x+1,x+2,……,x+y,长度为y+1。不断枚举更新答案即可,最后取最长连续序列的长度返回。
class Solution {
public int longestConsecutive(int[] nums) {
Set<Integer> num_set = new HashSet<Integer>();
for (int num : nums) {
num_set.add(num);
}
int longestStreak = 0;
for (int num : num_set) {
if (!num_set.contains(num - 1)) {
int currentNum = num;
int currentStreak = 1;
while (num_set.contains(currentNum + 1)) {
currentNum += 1;
currentStreak += 1;
}
longestStreak = Math.max(longestStreak, currentStreak);
}
}
return longestStreak;
}
}
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/longest-consecutive-sequence/solution/zui-chang-lian-xu-xu-lie-by-leetcode-solution/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

浙公网安备 33010602011771号