Description:
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
For example,
Given [100, 4, 200, 1, 3, 2],
The longest consecutive elements sequence is [1, 2, 3, 4]. Return its length: 4.
Your algorithm should run in O(n) complexity.
问题描述:
给定一个未排序的整数数组,找出最长连续序列的长度。
例子:
输入为[100, 4, 200, 1, 3, 2]
最长连续序列为[1, 2, 3 , 4],因此返回4
解法1:
/*
对数组排序,迭代数组,对数组划分连续区间,找出最长的连续区间,划分规则如下:
start = nums[0], maxCount为最长连续区间的长度,segCount为当前区间的长度
若nums[i] = start + 1,则当前区间长度+1,将start置为nums[i]
若nums[i] > start + 1,maxCount = Math.max(maxCount, segCount),将start置为nums[i], segCount = 1(开始新区间)
若nums[i] = start(由于已经排好序,只剩下这种可能),则忽略
*/
class Solution {
public int longestConsecutive(int[] nums) {
if(nums == null || nums.length == 0) return 0;
int maxCount = 1,segCount = 1;
Arrays.sort(nums);
int start = nums[0];
for(int i = 1;i < nums.length;i++){
if(nums[i] == start + 1){
segCount++;
start = nums[i];
}else if(nums[i] > start + 1){
start = nums[i];
maxCount = Math.max(segCount, maxCount);
segCount = 1;
}
}
return Math.max(segCount, maxCount);
}
}
解法2(并查集):
/*
并查集的关键是两个方法,find(),用于找出根节点,Union()用于合并
有两点需要注意:
1.map相当于'过滤'了重复元素,只取最右边的那个下标
2.sz数组存储的即为区间长度
*/
class Solution {
public int longestConsecutive(int[] nums) {
int n = nums.length;
UnionFind uf = new UnionFind(n);
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < n; i++) map.put(nums[i], i);
for (int num : nums)
if (map.containsKey(num+1))
uf.union(map.get(num), map.get(num+1));
return uf.getMaxSize();
}
private class UnionFind {
private int[] id;
private int[] sz;
private int maxSize;
public UnionFind(int n) {
id = new int[n];
sz = new int[n];
for (int i = 0; i < n; i++) {
id[i] = i;
sz[i] = 1;
}
maxSize = n > 0 ? 1 : 0;
}
public int findRoot(int i) {
if (i == id[i]) return i;
id[i] = findRoot(id[i]);
return id[i];
}
public void union(int p, int q) {
int rootP = findRoot(p);
int rootQ = findRoot(q);
if (rootP == rootQ) return;
if (sz[rootP] < sz[rootQ]) {
id[rootP] = rootQ;
sz[rootQ] += sz[rootP];
maxSize = Math.max(maxSize, sz[rootQ]);
} else {
id[rootQ] = rootP;
sz[rootP] += sz[rootQ];
maxSize = Math.max(maxSize, sz[rootP]);
}
}
public int getMaxSize() {
return this.maxSize;
}
}
}
虽然第一种解法最快(beats 100%),也是有必要掌握并查集算法的。