题解:Leetcode959--由斜杠划分区域(并查集)
题目概述:
在由 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.将每个方块划分成上下左右四小方块
2.对于每一个大方块里的小方块,根据字符是/还是\还是空格,进行不同的合并操作
3.对于大方块与大方块之间,左右两个小方块可以合并,上下两个小方块可以合并
4.并查集的使用:如果发现合并的时候,合并的两个小方块的父亲都是同一个,证明二者其实已经合并过的(二者已经联通),不需要再次合并
代码:
1 class Solution { 2 public: 3 int father[3605];//记录每个小方块的“父亲” 4 int number;//记录区域数量 5 int square[3605];//记录小方块 6 int find(int x)//寻找小方块的父亲 7 { 8 if(father[x]==x)//如果它本身的父亲就是自己,那么找到头了,返回 9 { 10 return x; 11 } 12 else//如果父亲不是自己,则未寻找到底,继续寻找,并且把父亲记录更新成根节点 13 { 14 father[x]=find(father[x]); 15 return father[x]; 16 } 17 } 18 void gettogether(int a,int b)//合并 19 { 20 if(find(a)==find(b))//如果二者的父亲是同一个,则二者已经联通,不需要再次合并 21 { 22 return; 23 } 24 //这里涉及到一个问题,为什么合并的时候都要find一次而不是直接比较father[a]和father[b]呢?因为合并之后,某个小方块的father不一定是他的最终father,具有滞后性!重新find可以更新他的father! 25 else//如果不是同一个,那么先寻找到a的父亲,再让a的父亲成为b的父亲的儿子,这样a的父亲的一家子都是b的父亲的儿子了,这样就联通起来了 26 { 27 a=find(a); 28 father[a]=find(b); 29 number--;//数量减一 30 return; 31 } 32 33 } 34 int regionsBySlashes(vector<string>& grid) { 35 number=grid.size()*grid.size()*4; 36 for(int i=0;i<=3604;i++)//最开始让每个小方块的父亲都是自己 37 { 38 father[i]=i; 39 square[i]=i; 40 } 41 for(int i=0;i<grid.size();i++) 42 { 43 for(int j=0;j<grid.size();j++) 44 { 45 if(i<grid.size()-1)//如果不是最后一行,则该大方块可以和下面的大方块合并 46 { 47 gettogether(square[i*grid.size()*4+j*4+2],square[(i+1)*grid.size()*4+j*4]); 48 } 49 if(j<grid.size()-1)//如果不是最后一列,则该大方块可以和右边的大方块合并 50 { 51 gettogether(square[i*grid.size()*4+j*4+1],square[i*grid.size()*4+(j+1)*4+3]); 52 } 53 if(grid[i][j]=='/')//‘/’的合并方式 54 { 55 gettogether(square[i*grid.size()*4+j*4],square[i*grid.size()*4+j*4+3]); 56 gettogether(square[i*grid.size()*4+j*4+1],square[i*grid.size()*4+j*4+2]); 57 } 58 else if(grid[i][j]=='\\')//‘\’的合并方式 59 { 60 gettogether(square[i*grid.size()*4+j*4],square[i*grid.size()*4+j*4+1]); 61 gettogether(square[i*grid.size()*4+j*4+2],square[i*grid.size()*4+j*4+3]); 62 } 63 else if(grid[i][j]==' ')//空白的合并方式 64 { 65 gettogether(square[i*grid.size()*4+j*4],square[i*grid.size()*4+j*4+1]); 66 gettogether(square[i*grid.size()*4+j*4+2],square[i*grid.size()*4+j*4+3]); 67 gettogether(square[i*grid.size()*4+j*4],square[i*grid.size()*4+j*4+2]); 68 } 69 } 70 } 71 return number;//返回数量 72 } 73 };

浙公网安备 33010602011771号