130. Surrounded Regions
Leetcode Union Find Depth-First Search Breath-First SearchGiven a 2D board containing 'X'
and 'O'
(the letter O), capture all regions surrounded by 'X'
.
A region is captured by flipping all 'O'
s into 'X'
s in that surrounded region.
Example:
X X X X
X O O X
X X O X
X O X X
After running your function, the board should be:
X X X X
X X X X
X X X X
X O X X
Explanation:
Surrounded regions shouldn’t be on the border, which means that any 'O'
on the border of the board are not flipped to 'X'
. Any 'O'
that is not on the border and it is not connected to an 'O'
on the border will be flipped to 'X'
. Two cells are connected if they are adjacent cells connected horizontally or vertically.
分析¶
这道题其实思路是非常简单的:把二维数组放在UnionFind集合中,当出现'O'时,将'O'附近的'O'连接起来,形成connected component. 那么怎么判断'O'是否被围起来了呢?这里采用在原来数组外增加一圈'O'的方法,只需判断该'O'是否和外圈的'O'连接,来判断'O'是否被围起来。
public class Q130SurroundedRegions {
public static void solve(char[][] board) {
// corner case
if (board.length < 3) return;
int n = board.length;
int m = board[0].length;
// corner case
if (m < 3) return;
// add virtual points surrounds board
int nn = n + 2, mm = m + 2;
char[][] B = new char[nn][mm];
for (int i = 0; i < nn; i++) {
for (int j = 0; j < mm; j++) {
if (i == 0 || j == 0 || j == mm - 1 || i == nn - 1)
B[i][j] = 'O';
else
B[i][j] = board[i-1][j-1];
}
}
// add union find data structure, 0 as virtual point
WeightedPathCompressionQuickFind uf = new WeightedPathCompressionQuickFind(nn*mm);
int index;
for (int i = 0; i < nn; i++) {
for (int j = 0; j < mm; j++) {
index = i * mm + j;
if (virtualBoard[i][j] == 'O') {
// find adject 'O'
if ((j > 0) && (B[i][j-1] == 'O')) { //left
uf.union(index, index - 1);
}
if ((j < m - 1) && (B[i][j + 1] == 'O')) { // right
uf.union(index, index + 1);
}
if ((i > 0) && (B[i-1][j] == 'O')) { // top
uf.union(index, index - mm);
}
if ((i < n - 1) && (B[i+1][j] == 'O')) { // bottom
uf.union(index, index + mm);
}
}
}
}
// flip it if 'O' is captured,
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < m - 1; j++) {
index = (i + 1) * mm + (j + 1); // index on virtual board
if ((board[i][j] == 'O') && (!uf.connected(0, index))) {
board[i][j] = 'X';
}
}
}
}
}