被围绕的区域
https://www.nowcoder.com/practice/3946670643fe4ec2aedcc2be45aed1a9
import java.util.*;
/**
* NC226 被围绕的区域
* @author d3y1
*/
public class Solution {
private int[] dx = new int[]{0, 1, 0, -1};
private int[] dy = new int[]{1, 0, -1, 0};
private int ROW;
private int COL;
private boolean[][] isVisited;
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 程序入口
*
* @param board char字符型二维数组
* @return char字符型二维数组
*/
public char[][] surroundedArea (char[][] board) {
// return solution1(board);
return solution2(board);
}
/**
* 模拟法: 直接递归
* @param board
* @return
*/
private char[][] solution1(char[][] board){
ROW = board.length;
COL = board[0].length;
isVisited = new boolean[ROW][COL];
for(int i=0; i<ROW; i++){
for(int j=0; j<COL; j++){
if(board[i][j]=='O' && !isVisited[i][j]){
dfs(board, i, j);
}
}
}
return board;
}
/**
* dfs
* @param board
* @param x
* @param y
* @return
*/
private boolean dfs(char[][] board, int x, int y){
if(board[x][y] == 'X'){
return true;
}
// O -> X
board[x][y] = 'X';
isVisited[x][y] = true;
int nextX, nextY;
for(int i=0; i<4; i++){
nextX = x+dx[i];
nextY = y+dy[i];
// 不合法 超过边界
if(!isValid(nextX, nextY)){
// X -> O
board[x][y] = 'O';
return false;
}
// 未访问过
if(!isVisited[nextX][nextY]){
if(!dfs(board, nextX, nextY)){
// X -> O
board[x][y] = 'O';
return false;
}
}
// 已访问过
else{
// 已访问过 但是恢复成O => 说明相邻位置(nextX,nextY)未被围绕, 则当前位置(x,y)也不可能被围绕
if(board[nextX][nextY] == 'O'){
// X -> O
board[x][y] = 'O';
return false;
}
}
}
return true;
}
/**
* 模拟法: 边界递归
* @param board
* @return
*/
private char[][] solution2(char[][] board){
ROW = board.length;
COL = board[0].length;
// isVisited = new boolean[ROW][COL];
// 左右边界
for(int i=0; i<ROW; i++){
if(board[i][0] == 'O'){
dfsBorder(board, i, 0);
}
if(board[i][COL-1] == 'O'){
dfsBorder(board, i, COL-1);
}
}
// 上下边界
for(int j=0; j<COL; j++){
if(board[0][j] == 'O'){
dfsBorder(board, 0, j);
}
if(board[ROW-1][j] == 'O'){
dfsBorder(board, ROW-1, j);
}
}
// N -> O and O -> X
for(int i=0; i<ROW; i++){
for(int j=0; j<COL; j++){
if(board[i][j] == 'O'){
board[i][j] = 'X';
}
if(board[i][j] == 'N'){
board[i][j] = 'O';
}
}
}
return board;
}
/**
* dfs(边界)
* @param board
* @param x
* @param y
*/
private void dfsBorder(char[][] board, int x, int y){
// N-NO
if(board[x][y]=='X' || board[x][y]=='N'){
return;
}
// O -> N
board[x][y] = 'N';
int nextX, nextY;
for(int i=0; i<4; i++){
nextX = x+dx[i];
nextY = y+dy[i];
if(isValid(nextX, nextY)){
dfsBorder(board, nextX, nextY);
}
}
}
/**
* 是否合法(是否越界)
* @param x
* @param y
* @return
*/
private boolean isValid(int x, int y){
if(x<0 || x>=ROW || y<0 || y>=COL){
return false;
}
return true;
}
}