0
点赞
收藏
分享

微信扫一扫

LeetCode_Array_128. Longest Consecutive Sequence最长连续序列(C++)【并查集】


目录

​​1,题目描述​​

​​英文描述​​

​​中文描述​​

​​2,解题思路​​

​​第一博(set中元素递增)​​

​​第二搏(剪枝,每次都挑选一个完全新的开始元素x【不存在x-1】开始查找)​​

​​第三搏(并查集)​​

​​3,AC代码​​

​​第一博​​

​​第二搏​​

​​第三搏​​

​​4,解题过程​​

​​第一博​​

​​第二搏​​

​​第三搏​​

1,题目描述

英文描述

Given an unsorted array of integers, find the length of the longest consecutive elements sequence.

Your algorithm should run in O(n) complexity.

Example:

Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4.

中文描述

给定一个未排序的整数数组,找出最长连续序列的长度。

要求算法的时间复杂度为 O(n)。

示例:

输入: [100, 4, 200, 1, 3, 2]
输出: 4
解释: 最长连续序列是 [1, 2, 3, 4]。它的长度为 4。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/longest-consecutive-sequence
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2,解题思路

第一博(set中元素递增)

借助于STL中set的三个优点:无重复元素,元素按照默认递增排列,插入、查找、删除时间复杂度O(logN);

  • 先将数据依次插入set<int> record中,去重;
  • 接着遍历record中每个元素,若当前元素 *it 比上一元素lastNum大一,说明数据连续,更新连续数字的长度tem++;
  • 否则,说明连续中断,更新ans = max(ans, tem);

第二搏(剪枝,每次都挑选一个完全新的开始元素x【不存在x-1】开始查找)

参考​​@力扣官方题解【最长连续序列】​​

利用unordered_set去重,遍历去重后的每一个元素x;

若x - 1存在于原数组中,则跳过;

否则查看与x连续的元素最远可到达的位置;

根据最远的位置更新ans;

第三搏(并查集)

不熟悉并查集的同学可以看这里​​@&再见萤火虫&【并查集【算法笔记/晴神笔记】】​​

参考​​@leck【c++并查集写法,代码极短】​​

unordered_map<int, int> father:key元素,value元素对应父节点(这种数据结构可以调用函数count来查看key是否存在);

father初始化:father[i] = i + 1;(这样便可以依据father[i]来寻找源头);

find函数设计:采用递归+路径压缩的方式;

遍历时,找到每个元素x的根节点y,利用y-x更新ans;

举个例子:

  • 初始化map:[100:101,4:5,200:201,1:2,3:4,2:3];
  • 当遍历到1时,顺着找1-》2,2-》3,3-》4,4-》5,5-》5,所以ans更新为4;

 

3,AC代码

第一博

class Solution {
public:
int longestConsecutive(vector<int>& nums) {
if(nums.size() == 0) return 0;
set<int> record; // 是set而不是unordered_set
for(int x : nums) record.insert(x);
set<int>::iterator it = record.begin(); // 迭代器it
int ans = 0, lastNum = *it, tem = 1;
while(++it != record.end()){
if(*it == lastNum + 1) tem++;
else{
ans = max(ans, tem);
tem = 1;
}
lastNum = *it;
}
ans = max(ans, tem);
return ans;
}
};

第二搏

class Solution {
public:
int longestConsecutive(vector<int>& nums) {
int ans = 0;
unordered_set<int> record;
for(int x : nums) record.insert(x); // 去重
for(int x : record){
if(record.count(x - 1) == 0) {
int curNum = x;
int curAns = 1;
while(record.count(x + 1) != 0) {
curNum = ++x;
curAns++;
}
ans = max(ans, curAns);
}
}
return ans;
}
};

第三搏

class Solution {
public:
unordered_map<int, int> father;
int find(int x) {
if(father.count(x)) {
father[x] = find(father[x]); // 递归进行路径压缩
}else {
return x;
}
return father[x];
}
int longestConsecutive(vector<int>& nums) {
int ans = 0;
for(int x : nums)
father[x] = x + 1; // 每个节点的父亲初始化为x+1
for(int x : nums) {
int y = find(x);
ans = max(ans, y - x);
}
return ans;
}
};

4,解题过程

第一博

set集合内在数据结构为红黑树,插入、查看、删除的时间复杂度均为O(logN),而且存入set集合的元素有个特点,就是顺序按照字典序递增。

所以这一题侥幸过关了:set中插入所有元素,再次遍历,获得结果;

LeetCode_Array_128. Longest Consecutive Sequence最长连续序列(C++)【并查集】_LeetCode

第二搏

查看了官方题解,大致思路是先把所有元素插入到unordered_set中去重;

遍历去重后的数组元素x,若发现x - 1存在于数组中,则跳过;

否则就查看x+1、x+2、......x+i是否存在于数组中,并更新最大长度ans;

LeetCode_Array_128. Longest Consecutive Sequence最长连续序列(C++)【并查集】_C++_02

第三搏

看到有位大佬使用了并查集来做,感觉思路还挺巧的,于是拿来试一试,但是效率并不是太理想

LeetCode_Array_128. Longest Consecutive Sequence最长连续序列(C++)【并查集】_array_03

举报

相关推荐

0 条评论