0959-由斜杠划分区域
在由 1 x 1
方格组成的 n x n
网格 grid
中,每个 1 x 1
方块由 '/'
、'\'
或空格构成。这些字符会将方块划分为一些共边的区域。
给定网格 grid
表示为一个字符串数组,返回 区域的数量 。
请注意,反斜杠字符是转义的,因此 '\'
用 '\\'
表示。
示例 1:
**输入:** grid = [" /","/ "]
**输出:** 2
示例 2:
**输入:** grid = [" /"," "]
**输出:** 1
示例 3:
**输入:** grid = ["/\\","\\/"]
**输出:** 5
**解释:** 回想一下,因为 \ 字符是转义的,所以 "/\\" 表示 /\,而 "\\/" 表示 \/。
提示:
n == grid.length == grid[i].length
1 <= n <= 30
grid[i][j]
是'/'
、'\'
、或' '
📺 视频讲解
力扣君温馨小贴士:觉得视频时间长的扣友,可以在视频右下角的「设置」按钮处选择 1.5 倍速或者 2 倍速观看。
📖 文字解析
这是一个关于连通性的问题,让我们求解连通分量的个数,解决这个问题没有特别的技巧,根据题意 画图分析、稍微细心一点就可以通过系统测评。
可以用深度优先遍历(Depth First Search)、广度优先遍历(Breadth First Search)和并查集(Disjoint Sets),由于只要求计算结果,不要求给出具体的连通信息,可以使用并查集。
方法:并查集
「斜杠」、「反斜杠」把单元格拆分成的 2 个三角形的形态,在做合并的时候需要分类讨论。根据「斜杠」、「反斜杠」分割的特点,我们把一个单元格分割成逻辑上的 4 个部分。如下图所示:
{:width=500}
我们须要遍历一次输入的二维网格 grid
,在 单元格内 和 单元格间 进行合并。
单元格内:
- 如果是空格:合并 0、1、2、3;
- 如果是斜杠:合并 0、3,合并 1、2;
- 如果是反斜杠:合并 0、1,合并 2、3。
单元格间:
把每一个单元格拆分成 4 个小三角形以后,相邻的单元格须要合并,无须分类讨论。我们选择在遍历 grid
的每一个单元格的时候,分别「向右、向下」尝试合并。
{:width=300}
- 向右:合并 1 (当前单元格)和 3(当前单元格右边 1 列的单元格),上图中红色部分;
- 向下:合并 2 (当前单元格)和 0(当前单元格下边 1 列的单元格),上图中蓝色部分。
事实上,大家选择在遍历 grid
的每一个单元格的时候,分别「向左、向上」、「向左、向下」、「向右、向上」、「向右、向下」中的任何一种都可以。
合并完成以后,并查集里连通分量的个数就是题目要求的区域的个数。
参考代码:
1 | public class Solution { |
复杂度分析
- 时间复杂度:O(N^2 \log N),其中 N 是网格的长度,O(N^2 \log N^2) = O(2N^2 \log N);
- 空间复杂度:O(N^2)。
本题采用了「先拆后合」的策略,避免了相对复杂的分类讨论。