版权声明:本文为博主原创文章,未经博主允许不得转载。 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;
}