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
题目解析:
反向思索最简单:哪些‘O’是应该保留的?
从上下左右四个边界往里走,凡是能碰到的
‘O’ ,都是跟边界接壤的,应该保留。
思路:
对于每一个边界上的‘O’作为起点,做若干次广度
优先搜索,对于碰到的‘O’,标记为其他某字符Y;
最后遍历一遍整个地图,把所有的Y恢复成‘O’,把
所有现有的‘O’都改成‘X’。
public class Solution { static class Pair{ public int first; public int second; public Pair(int f, int s){ first = f; second = s; } } public static boolean isValid(Pair p, char[][] board){ int m= board.length; int n= board[0].length; int x = p.first; int y = p.second; if(x<0 || x>=m || y<0 ||y >=n || board[x][y]!='O') return false; return true; } public static List<Pair> state_extend(Pair pr, char[][] board){ int m= board.length; int n= board[0].length; List<Pair> result = new ArrayList<Pair>(); int x = pr.first; int y = pr.second; //上下左右 Pair[] new_states = {new Pair(x-1,y),new Pair(x+1,y), new Pair(x,y+1),new Pair(x,y-1)}; for(int k =0; k<4; ++k){ if(isValid(new_states[k],board)){ board[new_states[k].first][new_states[k].second] ='+'; result.add(new_states[k]); } } return result; } public void solve(char[][] board) { if(board.length ==0 )return ; //m,n赋值 int m = board.length; int n = board[0].length; for(int i = 0; i<n; i++){ bfs(board,0,i); bfs(board,m-1, i); } for(int j=1; j<m-1;j++){ bfs(board,j,0); bfs(board,j,n-1); } for(int i=0; i<m;i++){ for(int j =0; j<n; j++){ if( board[i][j] =='O')board[i][j]='X'; else if(board[i][j]=='+') board[i][j]='O'; } }//for }//solve public void bfs(char[][] board, int i, int j){ ArrayDeque<Pair> stack = new ArrayDeque<>(); int m = board.length; int n = board[0].length; Pair p = new Pair(i,j); if(isValid(p,board)){ board[i][j]='+'; stack.push(p); } List<Pair> list = new ArrayList<Pair>(); while(!stack.isEmpty()){ Pair cur = stack.pop(); list = state_extend(cur,board); for(Pair s: list) { stack.push(s); } } } }
网上方法,相对简洁
import java.util.LinkedList; import java.util.List; /** * 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. * * answer: 从上下左右四个边界找O,然后进行BFS,找到的都是要保留的,最后遍历一次修改字符即可。 * 特别注意有一个用例 board 是空,所以进行判断否则会导致RE * */ public class SurroundedRegions { class Point{ int x,y; Point(int i,int j){x=i;y=j;} } public void solve(char[][] board) { int m = board.length; if(m == 0){ //判空防止 run-time error,不能和 n 一起判断 return; } int n = board[0].length; if(n == 0){ //判空防止 run-time error return; } for(int i=0;i<m;i++){ bfs(board,i,0); bfs(board,i,n-1); } for(int j=0;j<n;j++){ bfs(board,0,j); bfs(board,m-1,j); } for(int i=0;i<m;i++){ for(int j=0;j<n;j++){ if(board[i][j] == 'O'){ board[i][j] = 'X'; }else if(board[i][j] == 'A'){ board[i][j] = 'O'; } } } } private void bfs(char[][] board,int x,int y){ if(board[x][y] != 'O'){ return ; } LinkedList<Point> queue = new LinkedList<>(); queue.add(new Point(x,y)); board[x][y] = 'A'; while(!queue.isEmpty()){ Point top = queue.poll(); int i = top.x; int j = top.y; addPoint(board,i-1,j,queue); addPoint(board,i+1,j,queue); addPoint(board,i,j-1,queue); addPoint(board,i,j+1,queue); } } private boolean addPoint(char[][] board,int x,int y,LinkedList<Point> queue){ if(x < 0 || x > board.length-1 || y < 0 || y > board[0].length-1 || board[x][y] != 'O'){ return false; }else{ queue.add(new Point(x,y)); board[x][y] = 'A'; return true; } } }