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 .
真是无奈了。。。。。
首先想到的是dfs。扫描board上的每一个点,如果发现了‘O’,就以这个点进行dfs。但是需要判断最后是否遇到了边界,如果遇到了那么需要标记出这些是应该为‘O’的,如果没有遇到需要标记这些相连的‘O’应该最后为‘X’。同时还有可能出现从一个点出发的一条路径没有遇到了边界,回溯到最开始的点,再dfs另一条路径,发现遇到了边界,还要将第一条路径上的点标记上最后应该为‘O’。
在考虑了这么多复杂的可能性后。。。发现runtime error。。。。。。是因为大数据的时候递归的太深了。但当时没有意识到时这个原因。
所以上网看到了说,对每个边界上的'O'进行dfs,如果是相连的那么最后应该为'O', 否则应该为'X'。。。擦。。怎么这么有道理呢。。。。。我咋没想到。。。
然后就照着这个思路再来一次dfs,发现依然是runtime error。。。。
1 public static void solve (char[][] board) { 2 int n = board.length; 3 if (n == 0) return; 4 int m = board[0].length; 5 if (n==1 && m==0) return; 6 for (int j=0; j<m; j++) { 7 if (board[0][j] == 'O') 8 dfs(board, 0, j); 9 if (board[n-1][j] == 'O') 10 dfs(board, n-1, j); 11 } 12 for (int i=0; i<n; i++) { 13 if (board[i][0] == 'O') 14 dfs(board, i, 0); 15 if (board[i][m-1] == 'O') 16 dfs(board, i, m-1); 17 } 18 19 20 21 for (int i=0; i<board.length; i++) { 22 for (int j=0; j<board[0].length; j++) { 23 if (board[i][j] == 'u') { 24 board[i][j] = 'O'; 25 } 26 else if (board[i][j] == 'O') { 27 board[i][j] = 'X'; 28 } 29 } 30 } 31 } 32 33 public static void dfs (char[][] board, int i, int j) { 34 int x = board[0].length; 35 int y = board.length; 36 37 board[i][j] = 'u'; 38 39 if (j>0 && board[i][j-1] == 'O') 40 dfs(board, i, j-1); 41 if (j<x-1 && board[i][j+1] == 'O') 42 dfs(board, i, j+1); 43 if (i>0 && board[i-1][j] == 'O') 44 dfs(board, i-1, j); 45 if (i<y-1 && board[i+1][j] == 'O') 46 dfs(board, i+1, j); 47 }
这个时候我想要不要用bfs。。。但是这个时候我竟然用了一种递归写出来bfs。。。依然是runtime error。。。后来我才意识到bfs原来是不用递归的。。。是用队列就可以实现了。。。依然是runtime error。。。我就看哪里还能优化。。。我发现最开始我是每遇到一个边界上的'O'我就进行bfs。。。。最后我改为先将边界上的所有的'O'统计起来之后再bfs。。。。。终于可以了。。。
还有值得一提的是对坐标的处理方式。。。i*col +j 这样就不用记录i,j两个数。。。。好厉害。。。
1 static Queue<Integer> queue = new LinkedList<Integer>(); 2 public static void solve2 (char[][] board) { 3 int row = board.length; 4 if (row == 0) return; 5 int col = board[0].length; 6 if (col == 0) return; 7 8 for (int j=0; j<col; j++) { 9 if (board[0][j] == 'O') { 10 queue.offer(0*col + j); 11 } 12 } 13 for (int j=0; j<col; j++) { 14 if (board[row-1][j] == 'O') { 15 queue.offer((row-1)*col + j); 16 } 17 } 18 for (int i=0; i<row; i++) { 19 if (board[i][0] == 'O') { 20 queue.offer(i*col + 0); 21 } 22 } 23 for (int i=0; i<row; i++) { 24 if (board[i][col-1] == 'O') { 25 queue.offer(i*col + col-1); 26 } 27 } 28 bfs(board); 29 30 for (int i=0; i<board.length; i++) { 31 for (int j=0; j<board[0].length; j++) { 32 if (board[i][j] == 'u') { 33 board[i][j] = 'O'; 34 } 35 else if (board[i][j] == 'O') { 36 board[i][j] = 'X'; 37 } 38 } 39 } 40 } 41 42 public static void bfs (char[][] board) { 43 int row = board.length; 44 int col = board[0].length; 45 46 while (!queue.isEmpty()) { 47 int tmp = queue.poll(); 48 int i = tmp / col; 49 int j = tmp % col; 50 51 if (board[i][j] != 'O') continue; 52 board[i][j] = 'u'; 53 54 if (j>0 && board[i][j-1] == 'O') { 55 queue.offer(i*col + j-1); 56 } 57 if (j<col-1 && board[i][j+1] == 'O') { 58 queue.offer(i*col + j+1); 59 } 60 if (i>0 && board[i-1][j] == 'O') { 61 queue.offer((i-1)*col + j); 62 } 63 if (i<row-1 && board[i+1][j] == 'O') { 64 queue.offer((i+1)*col + j); 65 } 66 } 67 }