765.情侣牵手
终于自己写出来一次了。。。
思路就是把一对情侣看作图的一个点,相邻座位的非情侣(不连通)要连通,一趟遍历后,并查集的连通分量的数量是非情侣的数量
class UnionFind{
public:
vector<int> parent;
vector<int> size;
int n;
int setCount;//连通分量数目
public:
UnionFind(int _n):n(_n),setCount(_n),parent(_n),size(_n,1){
iota(parent.begin(),parent.end(),0);//范围赋值
}
int findset(int x){//找根节点
return parent[x] == x?x:parent[x] = findset(parent[x]);
}
bool unite(int x,int y){//合并
x = findset(x);
y = findset(y);
if(x==y){
return false;
}
if (size[x]<size[y]){
swap(x,y);
}
parent[y]=x;
size[x]+=size[y];
--setCount;
return true;
}
bool connected(int x,int y){//判断是否连接
x = findset(x);
y = findset(y);
return x==y;
}
};
class Solution {
public:
int minSwapsCouples(vector<int>& row) {
int n=row.size();
UnionFind uf = UnionFind(n/2);
for(int i=0;i<n;i+=2){//把不连通的点连通(非情侣挨着坐变成情侣挨着坐,unite一次连通分量数减一)
if(!uf.connected(row[i]/2,row[i+1]/2))
uf.unite(row[i]/2,row[i+1]/2);
}
return n/2-uf.setCount;//原来的连通分量数减去遍历后,就是交换的次数
}
};