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
边缘搜索替换法
复杂度
时间 O(MN) 空间 O(MN)
思路
从矩阵的四条边上的点作为起点,搜索连续的一块区域上值为O的点并赋为一个临时变量。这里我们用BFS或DFS进行搜索。对四条边上所有点都进行过这个步骤后,矩阵内剩余的O就是被包围的O。此时再对所有点遍历一遍,将临时变量赋回O,而剩余的O则赋为X。
注意
用队列实现BFS时,赋临时变量B时要在将周边点加入队列时就赋值,减少while循环的次数,否则Leetcode会超时
代码
广度优先 BFS
public class Solution {
public void solve(char[][] board) {
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if((i == 0 || j == 0 || i == board.length - 1 || j == board[0].length - 1) && (board[i][j]=='O')){
Queue<Integer> q = new LinkedList<Integer>();
q.offer(i * board[0].length + j);
board[i][j] = 'B';
while(!q.isEmpty()){
Integer key = q.poll();
int x = key / board[0].length;
int y = key % board[0].length;
if(x > 0 && board[x-1][y]=='O'){
q.offer((x-1) * board[0].length + y);
board[x-1][y] = 'B';
}
if(x < board.length - 1 && board[x+1][y]=='O'){
q.offer((x+1) * board[0].length + y);
board[x+1][y] = 'B';
}
if(y > 0 && board[x][y-1]=='O'){
q.offer(x * board[0].length + y - 1);
board[x][y-1] = 'B';
}
if(y < board[0].length - 1 && board[x][y+1]=='O'){
q.offer(x * board[0].length + y + 1);
board[x][y+1] = 'B';
}
}
}
}
}
for(int i = 0; i < board.length; i++){
for(int j = 0; j < board[0].length; j++){
if(board[i][j]=='O') board[i][j]='X';
if(board[i][j]=='B') board[i][j]='O';
}
}
}
}
深度优先 DFS
public class Solution {
static class Pair {
public int first;
public int second;
public Pair(int f, int s) {
first = f;
second = s;
}
}
public void solve(char[][] board) {
if(board == null || board.length == 0) {
return ;
}
for(int i = 0; i < board[0].length; ++i) {
if(board[0][i] == 'O') {
markUnflippable(board,0,i);
}
}
for(int i = 0; i < board[board.length-1].length; ++i) {
if(board[board.length-1][i] == 'O') {
markUnflippable(board,board.length-1,i);
}
}
for(int i = 0 ; i < board.length; ++i) {
if(board[i][0] == 'O') {
markUnflippable(board,i,0);
}
}
for(int i =0; i < board.length; ++i) {
if(board[i][board[i].length-1] == 'O') {
markUnflippable(board,i,board[i].length-1);
}
}
// modify the board
for(int i = 0; i < board.length; ++i) {
for(int j = 0; j < board[i].length; ++j) {
if(board[i][j] == 'O') {
board[i][j] = 'X';
} else if(board[i][j] == 'U') {
board[i][j] = 'O';
}
}
}
}
public void markUnflippable(char[][] board, int r, int c) {
int[] dirX = {-1,0,1,0};
int[] dirY = {0,1,0,-1};
ArrayDeque<Pair> stack = new ArrayDeque<>();
stack.push(new Pair(r,c));
while(!stack.isEmpty()) {
Pair p = stack.pop();
board[p.first][p.second] = 'U';
for(int i = 0; i < dirX.length; ++i) {
if(p.first + dirX[i] >= 0 && p.first + dirX[i] < board.length && p.second + dirY[i] >= 0 && p.second +dirY[i] < board[p.first + dirX[i]].length && board[p.first+dirX[i]][p.second+dirY[i]] == 'O') {
stack.push(new Pair(p.first+dirX[i],p.second+dirY[i]));
}
}
}
}
}