题目:
题解:
- 思路的话,把题目意思读懂了,直接看代码就好了。关于此题的标签还有
并查集
,我本人还没有学过,先留坑,以后慢慢填吧。
代码如下:
class Solution {
public:
//题解1:动态规划,时间复杂度O(nlogn),空间复杂度O(n)
//思路:利用sort先排序在去重,然后求解dp数组。状态转移方程:若nums[i-1]+1==nums[i],那么dp[i]=dp[i-1]+1,否则dp[i]=1
int longestConsecutive_1(vector<int>& nums) {
if(nums.size()<2)return nums.size();
sort(nums.begin(),nums.end());
//删除重复元素
nums.erase(unique(nums.begin(),nums.end()),nums.end());
int res=1,n=nums.size();
vector<int> dp(n,1);
for(int i=1;i<n;++i){
if(nums[i-1]+1==nums[i]){
dp[i]=dp[i-1]+1;
}
res=max(res,dp[i]);
}
return res;
}
//题解2:利用rb-tree进行去重,时间复杂度O(n),set的插入和查找时间复杂度为O(logn),空间复杂度O(1)
int longestConsecutive_2(vector<int>& nums){
if(nums.size()<2)return nums.size();
set<int> s(nums.begin(),nums.end());
int res=1;
for(int num:s){
//剪枝:因为若num-1存在,那么num一定计算过最大长度了
if(s.count(num-1)!=0)continue;
int len=1;
while(s.count(num+1)!=0){
len++;
num++;
}
res=max(res,len);
}
return res;
}
//题解3:利用hashset进行去重,hashset的插入和查找时间复杂度为O(1),遍历的时间杂度为O(n),空间复杂度为O(1)
int longestConsecutive(vector<int>& nums){
if(nums.size()<2)return nums.size();
unordered_set<int> s(nums.begin(),nums.end());
int res=1;
for(int num:s){
//剪枝:若num-1存在于hashset之中,那么num位于该段连续子序列的中间位置,只有num位于这段子序列的左边界时,才能一次就统计到这段子序列的长度,避免多次统计该段子序列的子子序列
if(s.count(num-1)!=0)continue;
int len=1;
while(s.count(num+1)!=0){
len++;
num++;
}
res=max(res,len);
}
return res;
}
};