LeetCode 128.最长连续序列(Longest Consecutive Sequence)【并查集】

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Ming991301630/article/details/81540182

中等难度题吧,不算hard题,需要了解并查集用法

将连续的数字进行合并成一个集合,最后看所有集合中哪个集合数目最多(或者直接边合并边记录最大值)
#include <vector>
#include <algorithm>
#include <unordered_map>
#include <set>
#include <map>
#include <unordered_set>
#include <iostream>
using namespace std;
class Solution {
    //并查集模板(已优化)
    struct DisJointSet
    {
        vector<int> _id;//元素
        vector<int> _size;//集合内的元素个数
        int max_size;//最大集合的元素个数【额外需要用到的参数】
        int _count;//集合总个数
        DisJointSet(int Num)
        {
            for (int i = 0; i < Num; i++)
            {
                _id.emplace_back(i);
                _size.emplace_back(1);
            }
            _count = Num;
            max_size = 1;
        }
        //查找
        int find_(int p)
        {
            while (p != _id[p])
            {
                _id[p] = _id[_id[p]];
                p = _id[p];
            }
            return p;
        }
        //合并
        void _union(int p, int q) {
            int i = find_(p);
            int j = find_(q);
            if (i == j)return;
            if (_size[i] > _size[j])
            {
                _id[j] = i;
                _size[i] += _size[j];
                max_size = max(max_size, _size[i]);
            }
            else
            {
                _id[i] = j;
                _size[j] += _size[i];
                max_size = max(max_size, _size[j]);
            }
            _count--;
        }
    };
public:
    int longestConsecutive(vector<int>& nums) {
        if (nums.size() == 0)return 0;
        DisJointSet disJointSet(nums.size());
        unordered_set<int> nums_set;//记录是否有查复数字 或者 是否已经有数字的前后的数
        unordered_map<int, int> nums_disJointSetID_map;//<数字,ID> 与并查集ID一一对应,不需改动模板参数
        for (int i = 0; i < nums.size(); i++)
        {
            if (nums_set.find(nums[i]) != nums_set.end())continue;
            nums_set.insert(nums[i]);
            nums_disJointSetID_map[nums[i]] = i;
            if(nums_set.find(nums[i] - 1) != nums_set.end())//是否有前一个数
            {
                disJointSet._union(nums_disJointSetID_map[nums[i]], nums_disJointSetID_map[nums[i] - 1]);
            }
            if(nums_set.find(nums[i] + 1) != nums_set.end())//是否有后一个数
            {
                disJointSet._union(nums_disJointSetID_map[nums[i]], nums_disJointSetID_map[nums[i] + 1]);
            }
        }
        return disJointSet.max_size;
    }
};

int main()
{
    Solution Solution;
    vector<int> nums{ 100,4,200,1,3,2 };
    cout << Solution.longestConsecutive(nums) << endl;
}

猜你喜欢

转载自blog.csdn.net/Ming991301630/article/details/81540182