[dp][并查集]leetcode128:最长连续序列(hard)

题目:
在这里插入图片描述
题解:

  • 思路的话,把题目意思读懂了,直接看代码就好了。关于此题的标签还有并查集,我本人还没有学过,先留坑,以后慢慢填吧。

代码如下:

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;
    }
};
发布了512 篇原创文章 · 获赞 175 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_43152052/article/details/104109841