最近刷题了解到了并查集这种数据结构,特意去学习了一下,并查集的写法大概有几种,但是关键点只有如下两点:
1.合并的方式(按高度或者按节点数);
2.路径压缩
写了几个模板
1.按高度合并同时进行路径压缩
class Union
{
public:
Union(int a):n(a)
{
cnt=n;
for(int i=0;i<n;++i)
{
parent.push_back(i);
rank.push_back(0);
}
}
int find(int p)
{
if(p!=parent[p])
{
parent[p]=find(parent[p]);
}
return parent[p];
}
void unite(int x,int y)
{
auto xpar=find(x);
auto ypar=find(y);
if(xpar==ypar)return;
--cnt;
if(rank[xpar]<rank[ypar])
{
parent[xpar]=ypar;
}
else
{
parent[ypar]=xpar;
if(rank[xpar]==rank[ypar])++rank[xpar];
}
}
bool same(int x,int y)
{
if(find(x)==find(y))return true;
return false;
}
int getcnt()
{
return cnt;
}
private:
vector<int>parent;
vector<int>rank;
int n;
int cnt;
};
2.按节点数合并同时进行路径压缩
class Union
{
public:
Union(int a):n(a)
{
cnt=n;
for(int i=0;i<n;++i)
{
parent.push_back(i);
size.push_back(1);
}
}
int find(int p)
{
if(p!=parent[p])
{
parent[p]=find(parent[p]);
}
return parent[p];
}
void unite(int x,int y)
{
auto xpar=find(x);
auto ypar=find(y);
if(xpar==ypar)return;
--cnt;
if(size[xpar]<size[ypar])
{
parent[xpar]=ypar;
size[ypar]+=size[xpar];
}
else
{
parent[ypar]=xpar;
size[xpar]+=size[ypar];
}
}
bool same(int x,int y)
{
if(find(x)==find(y))return true;
return false;
}
int getcnt()
{
return cnt;
}
private:
vector<int>parent;
vector<int>size;
int n;
int cnt;
};
用上面模板解决LeetCode1319题
LeetCode1319
这里省略了Union类的定义(如上所示)
class Solution {
public:
int makeConnected(int n, vector<vector<int>>& connections) {
int remain=0;
Union u(n);
for(auto c:connections)
{
auto x=c[0],y=c[1];
if(u.same(x,y)){++remain;continue;}
u.unite(x,y);
}
auto cnt=u.getcnt();
if(cnt-1>remain)return -1;
return cnt-1;
}
};
vector<int> findRedundantConnection(vector<vector<int>>& edges)
{
Union u(edges.size()+1);
vector<int>res(2,-1);
for(int i=0;i<edges.size();++i)
{
if(u.same(edges[i][0],edges[i][1]))
{
res[0]=edges[i][0];
res[1]=edges[i][1];
}
u.unite(edges[i][0],edges[i][1]);
}
return res;
}
};