题目
在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。
(请注意,反斜杠字符是转义的,因此 \ 用 “\” 表示。)。
返回区域的数目。
示例一
输入:
[
" /",
"/ "
]
输出:2
解释:2x2 网格如下:
思路分析
- 对于一个1*1的小方格来说,我们根据斜杠的方向相当于将其划分成了四个区域,如下图所示。对于合并来说,分为块内的合并和块间的合并。对于块内的合并,如果采用’/‘那么合并的是1,2和0,3;如果采用的是’’,合并的是0,1和2,3.对于块间的合并来说,如果采用’/‘那么合并的是1,2本来都是一个整体了,此时我们需要考虑的是1和右边的块0,2和下边的块0;如果采用的是’’,合并的是0,1本来都是一个整体了,此时我们需要考虑的是1和右边的块0,0和上边的块2。所以总的来说,需要考虑的是本块的1和右边的块3,本块的块2和下面的块0.
代码
class unionSet{
private:
vector<int> parent;
int count;
public:
void getParent(){
for(int i = 0;i < parent.size();i++) cout<<parent[i]<<" ";
cout<<endl;
}
unionSet(int n){
int total = 4 * n * n;
count = total;
parent = vector<int> (total , 0);
for(int i = 0;i < total;i++) parent[i] = i;
}
int find(int x){
if(x == parent[x]) return x;
return parent[x] = find(parent[x]);
}
void merge(int x, int y){
int rootx = find(x);
int rooty = find(y);
if(rootx == rooty){
return;
}
parent[rootx] = rooty;
count--;
}
int getCount(){
return count;
}
};
class Solution {
public:
int regionsBySlashes(vector<string>& grid) {
int n = grid.size();
unionSet s = unionSet(n);
// s.getParent();
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
int tot = 4 * (i * n + j);
char c = grid[i][j];
if(c == '/'){//合并0,3;合并1,2
s.merge(tot, tot + 3);
s.merge(tot + 1, tot + 2);
}else if(c == '\\'){//合并0,1;合并2,3
s.merge(tot, tot + 1);
s.merge(tot + 2, tot + 3);
}else{
s.merge(tot, tot + 1);
s.merge(tot + 1, tot + 2);
s.merge(tot + 2, tot + 3);
}
// cout<<"==========================="<<endl;
// s.getParent();
if(j + 1 < n){
s.merge(tot + 1, 4 * (i * n + j + 1) + 3);
}
// s.getParent();
if(i + 1 < n){
s.merge(tot + 2, 4 * ((i + 1) * n + j));
}
// s.getParent();
// cout<<"==========================="<<endl;
}
}
return s.getCount();
}
};