在由 1 x 1 方格组成的 N x N 网格 grid 中,每个 1 x 1 方块由 /、\ 或空格构成。这些字符会将方块划分为一些共边的区域。
(请注意,反斜杠字符是转义的,因此 \ 用 "\\" 表示。)。
返回区域的数目。
示例 1:
输入:
[
" /",
"/ "
]
输出:2
解释:2x2 网格如下:
示例 2:
输入:
[
" /",
" "
]
输出:1
解释:2x2 网格如下:
示例 3:
输入:
[
"\\/",
"/\\"
]
输出:4
解释:(回想一下,因为 \ 字符是转义的,所以 "\\/" 表示 \/,而 "/\\" 表示 /\。)
2x2 网格如下:
示例 4:
输入:
[
"/\\",
"\\/"
]
输出:5
解释:(回想一下,因为 \ 字符是转义的,所以 "/\\" 表示 /\,而 "\\/" 表示 \/。)
2x2 网格如下:
示例 5:
输入:
[
"//",
"/ "
]
输出:3
解释:2x2 网格如下:
提示:
1 <= grid.length == grid[0].length <= 30
grid[i][j] 是 '/'、'\'、或 ' '。
基本思路:求斜杠划分区域个数,容易想到并查集,但是怎么把现在的模型转换成可以使用并查集的情况,我们知道,一个单元格,最多被分为四分,所以我们可以把单元格划分为4份,然后根据情况连接。具体如上图所示
- 等价于把一个格子映射到4个区域0,1,2,3
- 注意,当前格子<i,j>的区域1必定和上一行<i-1,j>的区域3相连;当前格子<i,j>的区域0必定和左边<i,j-1>的区域2相连
- 如果是/,那么0,1相连,2,3相连;如果是\,那么1,2相连,0,3相连
vector<int> parent,psize;
int count=0;
int find(int x){
return x==parent[x]?x:parent[x]=find(parent[x]);
}
bool connect(int x,int y){
int rx=find(x);
int ry=find(y);
if(rx==ry)
return false;
if(psize[rx]<psize[ry])
swap(rx,ry);
parent[ry]=rx;
psize[rx]+=psize[ry];
count--;
return true;
}
void init(int n){
count=n;
parent.resize(n,0);
psize.resize(n,1);
for(int i=0;i<n;i++)
parent[i]=i;
}
int regionsBySlashes(vector<string>& grid) {
int n=grid.size();
auto getPos=[&n](int row,int col,int i)->int{return(row*n+col)*4+i;};
init(4*n*n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i>0){
connect(getPos(i,j,1),getPos(i-1,j,3)); //与上部连接
}
if(j>0){
connect(getPos(i,j,0),getPos(i,j-1,2)); //与左部连接
}
if(grid[i][j]=='/'){
connect(getPos(i,j,0),getPos(i,j,1));
connect(getPos(i,j,2),getPos(i,j,3));
}
else if(grid[i][j]=='\\'){
connect(getPos(i,j,1),getPos(i,j,2));
connect(getPos(i,j,0),getPos(i,j,3));
}
else{
connect(getPos(i,j,0),getPos(i,j,1));
connect(getPos(i,j,1),getPos(i,j,2));
connect(getPos(i,j,2),getPos(i,j,3));
}
}
}
return count;
}
基本思路2:我们也可以用dfs/bfs的方式,此时我们可以把一个单元格,映射到3*3的方格中,其中斜线代表的是中间的单元格为1
void dfs(vector<vector<int>> &ng,int x,int y){
if(x<0||x>=ng.size()||y<0||y>=ng.size()||ng[x][y])
return;
ng[x][y]=1;
dfs(ng,x-1,y);
dfs(ng,x+1,y);
dfs(ng,x,y-1);
dfs(ng,x,y+1);
}
int regionsBySlashes(vector<string>& grid) {
int n=grid.size();
int count=0;
vector<vector<int>> ng(3*n,vector<int>(3*n,0));//grid->ng映射
//初始化ng,把/,\限制条件加上
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(grid[i][j]=='/'){
ng[3*i][3*j+2]=ng[3*i+1][3*j+1]=ng[3*i+2][3*j]=1;
}
if(grid[i][j]=='\\'){
ng[3*i][3*j]=ng[3*i+1][3*j+1]=ng[3*i+2][3*j+2]=1;
}
}
}
//dfs遍历
for(int i=0;i<ng.size();i++){
for(int j=0;j<ng.size();j++){
if(ng[i][j]==0){
count++;
dfs(ng,i,j);
}
}
}
return count;
}