Leetcode128 “Longest Consecutive Sequence”
求一个数组的最长连续子序列
题目描述: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.
思路:
第一种方法 利用并查集的思想 使用Weighted-Quick-Union算法(路径压缩,合并优化) 进行实现
如果nums数组中的数不在map中 那么就把它放入
然后判断它的-1 和 +1的数 在不在map之中 如果在 就进行merge操作 更新size数组的值
Weighted-Quick-Union算法的思想是:根据两个集合的秩进行合并,所以哪个集合的元素数量多,merge的时候这个集合就成为父节点。
代码如下:
class Solution {
public:
vector<int> father;
vector<int> size;
public:
int longestConsecutive(vector<int>& nums) {
int n = nums.size();
if(n < 2) {
return n;
}
size = vector<int>(n, 1);
for(int i = 0; i < n; ++i) {
father.push_back(i);
}
unordered_map<int, int> m_map;
for(int i = 0; i < n; ++i) {
if(m_map.find(nums[i]) != m_map.end()) continue;
m_map[nums[i]] = i;
if(m_map.find(nums[i] - 1) != m_map.end()) {
unionset(i, m_map[nums[i] - 1]);
}
if(m_map.find(nums[i] + 1) != m_map.end()) {
unionset(i, m_map[nums[i] + 1]);
}
}
int ans = *max_element(size.begin(), size.end());
return ans;
}
int find(int idx) {//递归查找父节点 进行路径压缩
if(father[idx] == idx) {
return idx;
}
int father_idx = find(father[idx]);
father[idx] = father_idx;
return father_idx;
}
void unionset(int idx1, int idx2) {//进行merge操作
int p = find(idx1);
int q = find(idx2);
if(size[p] > size[q]) {
father[q] = p;
size[p] += size[q];
} else {
father[p] = q;
size[q] += size[p];
}
return ;
}
};