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.
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.
题目链接:https://leetcode.com/problems/surrounded-regions/
题目分析:先裸暴力DFS,时间6ms,击败15.63%
class Solution {
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
List<List<int[]>> flipList = new ArrayList<>();
boolean canFlip = true;
public void dfs(int x, int y, int n, int m, boolean[][] vis, char[][] board, List<int[]> region) {
region.add(new int[]{x, y});
vis[x][y] = true;
for (int i = 0; i < 4; i++) {
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 && yy >= 0 && xx < n && yy < m && board[xx][yy] == 'O' && !vis[xx][yy]) {
if (xx == 0 || yy == 0 || xx == n - 1 || yy == m - 1) {
canFlip = false;
}
dfs(xx, yy, n, m, vis, board, region);
}
}
}
public void solve(char[][] board) {
int n = board.length;
if (n == 0) {
return;
}
int m = board[0].length;
boolean[][] vis = new boolean[n][m];
List<int[]> region = new ArrayList<>();
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < m - 1; j++) {
if (board[i][j] == 'O' && !vis[i][j]) {
canFlip = true;
dfs(i, j, n, m, vis, board, region);
if (canFlip) {
for (int k = 0; k < region.size(); k++) {
int[] p = region.get(k);
board[p[0]][p[1]] = 'X';
}
flipList.add(region);
}
region.clear();
}
}
}
}
}
然后发现其实只需要从边界为O的点遍历即可,遍历不到的地方就是可翻转的
1ms,时间击败100%
class Solution {
int[] dx = {1, 0, -1, 0};
int[] dy = {0, 1, 0, -1};
public void help(int x, int y, int n, int m, boolean[][] vis, char[][] board) {
vis[x][y] = true;
for (int i = 0; i < 4; i++) {
int xx = x + dx[i];
int yy = y + dy[i];
if (xx >= 0 && yy >= 0 && xx < n && yy < m && board[xx][yy] == 'O' && !vis[xx][yy]) {
help(xx, yy, n, m, vis, board);
}
}
}
public void solve(char[][] board) {
int n = board.length;
if (n == 0) {
return;
}
int m = board[0].length;
boolean[][] vis = new boolean[n][m];
List<int[]> region = new ArrayList<>();
for (int i = 0; i < n; i++) {
if (board[i][0] == 'O' && !vis[i][0]) {
help(i, 0, n, m, vis, board);
}
if (board[i][m - 1] == 'O' && !vis[i][m - 1]) {
help(i, m - 1, n, m, vis, board);
}
}
for (int j = 0; j < m; j++) {
if (board[0][j] == 'O' && !vis[0][j]) {
help(0, j, n, m, vis, board);
}
if (board[n - 1][j] == 'O' && !vis[n - 1][j]) {
help(n - 1, j, n, m, vis, board);
}
}
for (int i = 1; i < n - 1; i++) {
for (int j = 1; j < m - 1; j++) {
if (board[i][j] == 'O' && !vis[i][j]) {
board[i][j] = 'X';
}
}
}
}
}