[leetcode] Surrounded Regions
Given a 2D board containing 'X'
and '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
https://oj.leetcode.com/problems/surrounded-regions/
思路:最外圈的‘O’肯定不会被包围,所以从这些‘O'开始dfs或者bfs搜索到的’O‘也不会被包围,最外层处理完毕后,剩下的O变为X即可。
public class Solution { public void solve(char[][] board) { if (board == null || board.length <= 2 || board[0].length <= 2) return; int m = board.length; int n = board[0].length; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { if (i == 0 || i == m - 1 || j == 0 || j == n - 1) { if (board[i][j] == 'O') bfs(board, i, j, m, n); } } for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { if (board[i][j] == 'O') { board[i][j] = 'X'; } if (board[i][j] == '$') board[i][j] = 'O'; } } private int dir[][] = { { -1, 0 }, { 1, 0 }, { 0, -1 }, { 0, 1 } }; void dfs(char[][] board, int i, int j, int m, int n) { if (i < 0 || j < 0 || i >= m || j >= n) return; if (board[i][j] != 'O') return; board[i][j] = '$'; for (int k = 0; k < 4; k++) { dfs(board, i + dir[k][0], j + dir[k][1], m, n); } } void bfs(char[][] board, int i, int j, int m, int n) { Queue<Integer> queue = new LinkedList<Integer>(); queue.add(i * n + j); board[i][j] = '$'; while (!queue.isEmpty()) { int cur = queue.remove(); int x = cur / n; int y = cur % n; for (int k = 0; k < 4; k++) { int newX = x + dir[k][0]; int newY = y + dir[k][1]; if (newX >= 0 && newX < m && newY >= 0 && newY < n) if (board[newX][newY] == 'O') { queue.add(newX * m + newY); board[newX][newY] = '$'; } } } } public static void main(String[] args) { char[][] board = { "XXX".toCharArray(), "XOX".toCharArray(), "XXX".toCharArray() }; String s = "OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"; char[][] board2 = new char[s.length()][s.length()]; for (int i = 0; i < s.length(); i++) { board2[i] = s.toCharArray(); } new Solution().solve(board); } }
第二遍记录:
dfs总是stackoverflow,有个case比较变态, bfs轻松过。
public class Solution { public void solve(char[][] board) { if(board==null||board.length<=2||board[0].length<=2) return; int m=board.length; int n=board[0].length; for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(i==0||j==0||i==m-1||j==n-1){ if(board[i][j]=='O') bfs(board,m,n,i,j); } } } for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(board[i][j]=='O') board[i][j]='X'; if(board[i][j]=='$') board[i][j]='O'; } } } private int[][] dir={{-1,0},{1,0},{0,-1},{0,1}}; private void bfs(char[][]board, int m,int n,int i,int j){ Queue<Integer> queue = new LinkedList<Integer>(); queue.add(i*n+j); board[i][j]='$'; while(!queue.isEmpty()){ int cur = queue.remove(); int x =cur/n; int y =cur%n; for(int k=0;k<4;k++){ int newX=x+dir[k][0]; int newY=y+dir[k][1]; if(newX>=0&&newX<m&&newY>=0&&newY<n&&board[newX][newY]=='O'){ queue.add(newX*n+newY); board[newX][newY]='$'; } } } } }
第三遍记录:
bfs的时候‘O’变‘$’忘记了,改完就过了。
public class Solution { public void solve(char[][] board) { if (board == null || board.length <= 2 || board[0].length <= 2) return; int n = board.length; int m = board[0].length; boolean[][] vis = new boolean[n][m]; // change outside O to $ for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (i == 0 || i == n - 1 || j == 0 || j == m - 1) { if (board[i][j] == 'O') { bfs(board, i, j, vis); } } } } // change O to X for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (board[i][j] == 'O') board[i][j] = 'X'; } } // change $ back to O for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (board[i][j] == '$') board[i][j] = 'O'; } } } private int[][] dir = { { -1, 0 }, { 1, 0 }, { 0, 1 }, { 0, -1 } }; private void bfs(char[][] board, int x, int y, boolean[][] vis) { vis[x][y] = true; board[x][y]='$'; int n = board.length; int m = board[0].length; Queue<Integer> queue = new LinkedList<Integer>(); queue.add(x * m + y); while (!queue.isEmpty()) { Integer out = queue.remove(); int p = out / m; int q = out % m; for (int i = 0; i < 4; i++) { int np = p + dir[i][0]; int nq = q + dir[i][1]; if (np >= 0 && np < n && nq >= 0 && nq < m && !vis[np][nq] && board[np][nq] == 'O') { vis[np][nq] = true; board[np][nq]='$'; queue.add(np * m + nq); } } } } }
参考: