Given 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.
For 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
因为最外层的不会被包围,那如果最外层某个位置为O,那么紧挨着它的所有位置的O都不会被包围,因此,实际上是使用BFS的方法,利用一个队列的数据结构。
class Node {
int row;
int col;
public Node(int row, int col) {
this.row = row;
this.col = col;
}
}
public void solve(char[][] board) {
if (board == null || board.length == 0)
return;
int m = board.length;
int n = board[0].length;
boolean[][] visited = new boolean[m][n];
Queue q = new LinkedList<>();
// 第一行和最后一行
for (int i = 0; i < n; i++) {
if (!visited[0][i] && board[0][i] == 'O')
bfs(board, 0, i, m, n, visited);
if (!visited[m - 1][i] && board[m - 1][i] == 'O')
bfs(board, m - 1, i, m, n, visited);
}
// 第一列和最后一列
for (int i = 0; i < m; i++) {
if (!visited[i][0] && board[i][0] == 'O')
bfs(board, i, 0, m, n, visited);
if (!visited[i][n - 1] && board[i][n - 1] == 'O')
bfs(board, i, n - 1, m, n, visited);
}
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++) {
if (!visited[i][j] && board[i][j] == 'O')
board[i][j] = 'X';
}
for (int i = 0; i < m; i++)
System.out.println(Arrays.toString(board[i]));
}
Queue q = new LinkedList<>();
// 加入队列的时候设置visited该结点为true
private void bfs(char[][] board, int row, int col,
int m, int n, boolean[][] visited) {
q.offer(new Node(row, col));
visited[row][col] = true;
while (!q.isEmpty()) {
Node tmp = q.poll();
row = tmp.row;
col = tmp.col;
if (row - 1 >= 0 && !visited[row - 1][col]
&& board[row - 1][col] == 'O') {
q.offer(new Node(row - 1, col));
visited[row - 1][col] = true;
}
if (row + 1 < m && !visited[row + 1][col]
&& board[row + 1][col] == 'O') {
q.offer(new Node(row + 1, col));
visited[row + 1][col] = true;
}
if (col - 1 >= 0 && !visited[row][col - 1]
&& board[row][col - 1] == 'O') {
q.offer(new Node(row, col - 1));
visited[row][col - 1] = true;
}
if (col + 1 < n && !visited[row][col + 1]
&& board[row][col + 1] == 'O') {
q.offer(new Node(row, col + 1));
visited[row][col + 1] = true;
}
}
}
class Node {
int row;
int col;
Node(int row, int col) {
this.row = row;
this.col = col;
}
}
public void solve(char[][] board) {
int m = board.length;
if (m <= 0)
return;
int n = board[0].length;
if (n <= 0)
return;
int[][] visited = new int[m][n];
Queue queue = new LinkedList<>();
for (int row = 0; row < m; row++)
for (int col = 0; col < n; col++)
visited[row][col] = 0;
for (int row = 0; row < m; row++) {
if (board[row][0] == 'O')
queue.offer(new Node(row, 0));
if (board[row][n - 1] == 'O')
queue.offer(new Node(row, n - 1));
}
for (int col = 0; col < n; col++) {
if (board[0][col] == 'O')
queue.offer(new Node(0, col));
if (board[m - 1][col] == 'O')
queue.offer(new Node(m - 1, col));
}
while (!queue.isEmpty()) {
Node tmp = queue.poll();
int row = tmp.row;
int col = tmp.col;
// 关键点,如果不是加入队列的时候访问设置1,那么需要加此判断
if (visited[row][col] == 1)
continue;
visited[row][col] = 1;
if (row + 1 < m && board[row + 1][col] == 'O'
&& visited[row + 1][col] == 0)
queue.offer(new Node(row + 1, col));
if (row - 1 >= 0 && board[row - 1][col] == 'O'
&& visited[row - 1][col] == 0)
queue.offer(new Node(row - 1, col));
if (col + 1 < n && board[row][col + 1] == 'O'
&& visited[row][col + 1] == 0)
queue.offer(new Node(row, col + 1));
if (col - 1 >= 0 && board[row][col - 1] == 'O'
&& visited[row][col - 1] == 0)
queue.offer(new Node(row, col - 1));
}
for (int row = 0; row < m; row++) {
for (int col = 0; col < n; col++) {
if (board[row][col] == 'O' && visited[row][col] == 0)
board[row][col] = 'X';
}
}
}
借助 leetcode.200. Number of Islands Java版(岛屿的数量)
深度搜索连通子图类的问题
public void solve(char[][] grid) {
if (grid == null)
return;
int rows = grid.length;
if (rows <= 0)
return;
int cols = grid[0].length;
if (cols <= 0)
return;
for (int i = 0; i < rows; i++) {
if (grid[i][0] == 'O')
dfsSearch(grid, i, 0);
if (grid[i][cols - 1] == 'O')
dfsSearch(grid, i, cols - 1);
}
for (int i = 0; i < cols; i++) {
if (grid[0][i] == 'O')
dfsSearch(grid, 0, i);
if (grid[rows - 1][i] == 'O')
dfsSearch(grid, rows - 1, i);
}
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
if (grid[i][j] == '*')
grid[i][j] = 'O';
else if (grid[i][j] == 'O')
grid[i][j] = 'X';
for (int i = 0; i < rows; i++)
System.out.println(Arrays.toString(grid[i]));
}
// 每遇到'O'后, 开始向四个方向 递归搜索. 搜到后变为'*',
// 因为相邻的属于一个island. 然后开始继续找下一个'O'.
private void dfsSearch(char[][] grid, int i, int j) {
if (grid[i][j] == 'O') {
// 修改为一个不相干的字符,但不能是X
grid[i][j] = '*';// 和visited数组一样功能
// 不需要处理四周边缘了,调用循环已经处理过,不然超时
if (i < grid.length - 2)
dfsSearch(grid, i + 1, j);
if (i > 1)
dfsSearch(grid, i - 1, j);
if (j < grid[0].length - 2)
dfsSearch(grid, i, j + 1);
if (j > 1)
dfsSearch(grid, i, j - 1);
}
}