题目:https://leetcode.com/problems/regions-cut-by-slashes/description/
Solution1: DFS
Time Complexity:: $O(n^2)$
分析:
这个神奇的思路分割格子,转化为图的DFS问题。1
2
3
4
5Input:
[
"\\/",
"/\\"
]
把\\
,/
或者分别分割成3*3的格子。图转化为:
1 | [ |
问题就变成: 计算被1分割开的区域的数量。
类似的孤岛数量问题 都是同一个问题的变种:Counting the number of connected components in an undirected graph
1 | void dfs(vector<vector<int>>& board, int i, int j ) { |
如果分割为2*2的格子,会遇到这个问题:1
2
3
4
5
6
7
8
9
10
11
12Input:
[
"//",
"/ "
]
Output: 5
Expected: 3
0101
1010
0100
1000
0101
1010
0100
1000
加粗的这三个0,被分割开了。题意要求是连在一起的。
Solution2: DSU
Time Complexity: $O(n^2*\alpha(n))$
Space Complexity: $O(n^2)$
分析:
DSU:
https://www.youtube.com/watch?v=YKE4Vd1ysPI
https://www.youtube.com/watch?v=gpmOaSBcbYA
DSU中用数组来表示树, 如下:
idx | 0 | 1 | 2 |
---|---|---|---|
parent | 1 | -1 | 1 |
parent[0] = 1, 代表node 0的parent是1; parent[2] = 1代表node 2的parent是1; parent[1] = -1, 代表它是root。
1 | 1 |
两个operation:
find(x): find root of cluster in which x is
1 | 1 5 |
比如: 我们想找3跟8所在cluster的root, find(3) == 1, find(8) == 5
1 | /*递归查找root*/ |
union(x, y): union two cluster where x, y are in
比如: 我们想union(3, 8), 就要先找到3的x_root, 跟8的y_root,然后合并两个root.
1 | int union(int x, int y, int parent[]) { |
1 | 5 |
DSU腻害的一点是优化后,用$O(1)$的average time cost, 检测图里有咩有环
两种优化:
- Make tree flat
- Union by rank
https://www.youtube.com/watch?v=VJnUwsE4fWA
分割成4个三角形, 上下左右
每个格子分割成上下左右四个三角形。
https://assets.leetcode.com/uploads/2018/12/15/3.png
每个三角形给个idx: 0, 1, 2, 3分别对应 top, right, bottom, left1
2
3\ 0 /
3 \ 1
/ 2 \
nn的图;变成 4n*n的数组。 初始化时数组parent的每个值都是-1, 代表每个点都是独立的。我们遍历grid中的每个点, grid[i][j], 分别进行如下操作:
‘/‘: 上、左连接; 下、右连接
‘\‘: 上、右连接; 左、下连接
‘ ‘: 四个部分连接
对每个grid[i][j], 合并grid[i-1][j]的bottom三角形根grid[i][j]的top 三角形;合并grid[i][j-1]的right三角形跟grid[i][j]的left三角形。
最终代码如下:
1 | class DSU { |
scan qr code and share this article