题目:由斜杠划分区域
原题链接: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();
}
};