刷題筆記:並查集(續,LeetCode-959)
阿新 • • 發佈:2021-01-27
題目:由斜槓劃分區域
原題連結:https://leetcode-cn.com/problems/regions-cut-by-slashes/
解析
題目需要求解連通塊的個數,我們可以通過並查集進行求解,將聯通的區域合併成同一個集合,最後求解集合的個數。
觀察下圖,我們把單元格分為4個三角形,並進行編號。
對單元格內的合併:
- 如果是空格‘ ’,我們將(0,1,2,3)進行合併
- 如果是斜槓‘/’,我們將(0,3),(1,2)進行合併
- 如果是反斜槓‘\’,我們將(0,1),(2,3)進行合併
對相鄰單元格的合併,有4種方案:
- 向右和向下
- 向右和向上
- 向左和向下
- 向左和向上
在這裡,我使用向右和向下合併。
程式碼
class UnionFind {
private:
int count;
vector<int> father;
public:
int getCount(){
return this->count;
}
UnionFind(int n){
this->count=n;
father.resize(n);
for(int i=0;i<n;i++) father[i]=i;
}
int find_fa(int x){
if (x==father[x]) return x;
else {
int f=this->find_fa(father[x]);
father[x]=f;
return f;
}
}
void unino(int a,int b){
int fa=this->find_fa(a);
int fb=this->find_fa(b);
if(fa!=fb) {
father[fa]=fb;
this ->count--;
}
}
};
class Solution {
public:
int regionsBySlashes(vector<string>& grid) {
int len=grid.size();
int N=4*len*len;
UnionFind uf(N);
for(int i=0;i<len;i++){
int r=grid[i].size();
for(int j=0;j<r;j++){
int index=4*(i*len+j);
//合併正方形內
if(grid[i][j]=='/'){ //合併(0,3),(1,2)
uf.unino(index,index+3);
uf.unino(index+1,index+2);
}else if(grid[i][j]=='\\'){ //合併(0,1),(2,3)
uf.unino(index,index+1);
uf.unino(index+2,index+3);
}else{
uf.unino(index,index+1);
uf.unino(index+1,index+2);
uf.unino(index+2,index+3);
}
//合併區間外,向右,向下
if(j+1<len){ //向右合併
uf.unino(index+1,4*(i*len+j+1)+3);
}
if(i+1<len){
uf.unino(index+2,4*((i+1)*len+j));
}
}
}
return uf.getCount();
}
};