959. Regions Cut By Slashes
In a N x N grid
composed of 1 x 1 squares, each 1 x 1 square consists of a /
, \
, or blank space. These characters divide the square into contiguous regions.
(Note that backslash characters are escaped, so a \
is represented as "\\"
.)
Return the number of regions.
Example 1:
Input: [ " /", "/ " ] Output: 2 Explanation: The 2x2 grid is as follows:
Example 2:
Input: [ " /", " " ] Output: 1 Explanation: The 2x2 grid is as follows:
Example 3:
Input: [ "\\/", "/\\" ] Output: 4 Explanation: (Recall that because \ characters are escaped, "\\/" refers to \/, and "/\\" refers to /\.) The 2x2 grid is as follows:
Example 4:
Input: [ "/\\", "\\/" ] Output: 5 Explanation: (Recall that because \ characters are escaped, "/\\" refers to /\, and "\\/" refers to \/.) The 2x2 grid is as follows:
Example 5:
Input: [ "//", "/ " ] Output: 3 Explanation: The 2x2 grid is as follows:
这题的重点是怎么转化成union find,
在看了一个题解以后豁然开朗,但是实现的时候又或多或少有点小问题,有的时候index真的是很恼人,
或者说自己没有在脑袋里把它想清楚
我们先把一个正方形(小正方形)划分成四个区域,按照对角线划分
对于每一个小的正方形, 根据输入,可以有三种merge的方式
1. \:左下方的两个区域进行merge,
2. /:右上方的两个区域merge
3 ‘ ‘: 如果为空, 那么4个区域都需要merge,那么只需要进行三次eg: merge(0, 1), merge(0, 2) merge(0, 3)
以上就完成了正方形内部的union操作
继续观察,我们可以发现,由于每个小的正方形只有以上三种操作,所以必会得到以下的性质:
1. 正方形的下区域,会跟它下面相邻的正方形的上区域相邻
2. 正方形的右侧区域,会跟它右侧相邻的正方形的左侧相邻, 只要不是最后一行,最后一列,我们都需要进行merge操作
最后要弄清楚的就是index了.
我们吧整个大正方形分成了:
N * N 个正方形,然后每个小正方形,所以, 初始状态,一共是 4 * N * N 个集合, 然后通过上述的规则去进行合并,
合并的时候,要找到正确的index就可以了
代码:
class Solution {
/**
* Make each region split into 4 regions,
* @param grid
* @return
*/
public int regionsBySlashes(String[] grid) {
if(grid == null || grid.length == 0) return 0;
int row = grid.length;
int col = grid[0].length();
int[] parent = new int[row * col * 4];
// init
for(int i=0;i<parent.length;i++) parent[i] = i;
for(int i=0;i<row;i++) {
char[] line = grid[i].toCharArray();
for(int j=0;j<col;j++) {
int index = 4 * i * col + j*4 ;
if(line[j] == '\\') {
union(index+0, index+1, parent);
union(index+2, index+3, parent);
} else if(line[j] == '/') {
union(index+0, index+3, parent);
union(index+2, index+1, parent);
} else if(line[j] == ' ') {
union(index+0, index+1, parent);
union(index+0, index+2, parent);
union(index+0, index+3, parent);
}
// if it is not the last, row, index merge externally
if(i<row-1) {
union(index+2, index + 4*col+0, parent);
}
if(j<col-1) {
union(index+1, index + 4 + 3, parent);
}
}
}
int count=0;
for(int i=0;i<parent.length;i++) {
if(parent[i] == i) {
count++;
}
}
return count;
}
private void union(int x, int y, int[] parent) {
int xp = find(x, parent);
int yp = find(y, parent);
if(xp != yp) {
parent[xp] = yp;
}
}
private int find(int x, int[] parent) {
if(parent[x] != x) {
return parent[x] = find(parent[x], parent);
}
return x;
}
}