题目: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.
例子:
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
方法1:要将所有以O组成、但不连通到网格边缘的区域变为X。所以我们可以先在四边上寻找连通到边缘的区域,将它们的O都变成Y。剩余的所有O一定无法连通到边缘,所以可以全部变为X。最后再将所有Y变回O。使用迭代版的DFS实现flood fill,当然也可以用BFS实现。
class Solution {
public:
void solve(vector<vector<char>> &board) {
if(board.size()<3 || board[0].size()<3) return;
fillBorders(board, 'O', 'Y');
replace(board, 'O', 'X');
fillBorders(board, 'Y', 'O');
}
//迭代版的DFS
void fill(vector<vector<char>> &board, int i, int j, char target, char c) {
int m = board.size(), n = board[0].size();
if(i<0 || j<0 || i>=m || j>=n || board[i][j]!=target) return;
stack<pair<int,int>> s;
s.push(make_pair(i,j));
while(!s.empty()) {
i = s.top().first;
j = s.top().second;
s.pop();
board[i][j] = c;
if(i>0 && board[i-1][j]==target) s.push(make_pair(i-1,j));
if(i<m-1 && board[i+1][j]==target) s.push(make_pair(i+1,j));
if(j>0 && board[i][j-1]==target) s.push(make_pair(i,j-1));
if(j<n-1 && board[i][j+1]==target) s.push(make_pair(i,j+1));
}
}
void fillBorders(vector<vector<char>> &board, char target, char c) {
int m = board.size(), n = board[0].size();
for(int i=0; i<m; i++) {
if(board[i][0]==target) fill(board, i, 0, target, c);
if(board[i][n-1]==target) fill(board, i, n-1, target, c);
}
for(int j=1; j<n-1; j++) {
if(board[0][j]==target) fill(board, 0, j, target, c);
if(board[m-1][j]==target) fill(board, m-1, j, target, c);
}
}
void replace(vector<vector<char>> &board, char target, char c) {
int m = board.size(), n = board[0].size();
for(int i=0; i<m; i++) {
for(int j=0; j<n; j++) {
if(board[i][j]==target)
board[i][j] = c;
}
}
}
};
方法2:BFS
public class Solution {
static final int[] directionX = {+1, -1, 0, 0};
static final int[] directionY = {0, 0, +1, -1};
static final char FREE = 'F';
static final char TRAVELED = 'T';
public void solve(char[][] board) {
if (board.length == 0) {
return;
}
int row = board.length;
int col = board[0].length;
for (int i = 0; i < row; i++) {
bfs(board, i, 0);
bfs(board, i, col - 1);
}
for (int j = 1; j < col - 1; j++) {
bfs(board, 0, j);
bfs(board, row - 1, j);
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
switch(board[i][j]) {
case 'O':
board[i][j] = 'X';
break;
case 'F':
board[i][j] = 'O';
}
}
}
}
public void bfs(char[][] board, int i, int j) {
if (board[i][j] != 'O') {
return;
}
Queue<Node> queue = new LinkedList<Node>();
queue.offer(new Node(i, j));
while (!queue.isEmpty()) {
Node crt = queue.poll();
board[crt.x][crt.y] = FREE;
for (Node node : expand(board, crt)) {
queue.offer(node);
}
}
}
private List<Node> expand(char[][] board, Node node) {
List<Node> expansion = new ArrayList<Node>();
for (int i = 0; i < directionX.length; i++) {
int x = node.x + directionX[i];
int y = node.y + directionY[i];
// check validity
if (x >= 0 && x < board.length && y >= 0 && y < board[0].length && board[x][y] == 'O') {
board[x][y] = TRAVELED;
expansion.add(new Node(x, y));
}
}
return expansion;
}
static class Node {
int x;
int y;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
}
方法3:(九章算法上题解,没理解代码)
public class Solution {
private static Queue<Integer> queue = null;
private static char[][] board;
private static int rows = 0;
private static int cols = 0;
public void solve(char[][] board) {
// Note: The Solution object is instantiated only once and is reused by each test case.
if (board.length == 0 || board[0].length == 0) return;
queue = new LinkedList<Integer>();
board = board;
rows = board.length;
cols = board[0].length;
for (int i = 0; i < rows; i++) { // **important**
enqueue(i, 0);
enqueue(i, cols - 1);
}
for (int j = 1; j < cols - 1; j++) { // **important**
enqueue(0, j);
enqueue(rows - 1, j);
}
while (!queue.isEmpty()) {
int cur = queue.poll();
int x = cur / cols,
y = cur % cols;
if (board[x][y] == 'O') {
board[x][y] = 'D';
}
enqueue(x - 1, y);
enqueue(x + 1, y);
enqueue(x, y - 1);
enqueue(x, y + 1);
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (board[i][j] == 'D') board[i][j] = 'O';
else if (board[i][j] == 'O') board[i][j] = 'X';
}
}
queue = null;
board = null;
rows = 0;
cols = 0;
}
public static void enqueue(int x, int y) {
if (x >= 0 && x < rows && y >= 0 && y < cols && board[x][y] == 'O'){
queue.offer(x * cols + y);
}
}
}