题目描述:
现在有一个仅包含‘X’和‘O’的二维板,请捕获所有的被‘X’包围的区域
捕获一个被包围区域的方法是将被包围区域中的所有‘O’变成‘X’
例如 :
X X X X↵X O O X↵X X O X↵X O X X
执行完你给出的函数以后,这个二维板应该变成:
X X X X↵X X X X↵X X X X↵X O X X
分析:
给定二维数组将数组中所有被‘X’包围的’O’替换成’X’,没有被包围的则保留。数组中的边界位置的’O’一定不会被替换,因此与其连接到的’O’也不会被替换,所以应该先找到四个边界上的’O’,并且找到与之相连接的’O’,将其都置为其他字符。
该题目类似于迷宫问题(回溯算法)也就是递归算法。(可以参考上硅谷的算法与数据结构课中的递归讲解之迷宫问题)
public class Solution {
int brow=0;//行数
int bcol=0;//列数
public void solve(char[][] board) {
if(board==null||board.length<=0||board[0].length<=0){
return;
}
brow=board.length;//行数
bcol=board[0].length;//列数
for(int i=0;i<bcol;i++){ //固定行时以列为边界
reserve(board,0,i);//第一行
reserve(board,brow-1,i);//最后一行
}
for(int i=0;i<brow;i++){//固定列时以行为边界
reserve(board,i,0);//第一列
reserve(board,i,bcol-1);//最后一列
}
//替换的元素一定存在于非边界的元素中因此遍历中间的位置
for(int i=1;i<board.length-1;i++){
for(int j=1;j<board[0].length-1;j++){
if(board[i][j]=='O'){
board[i][j]='X';
}
}
}
//将元素中边界以及其连接点的元素换回原来的'O'
for(int i=0;i<board.length;i++){
for(int j=0;j<board[0].length;j++){
if(board[i][j]=='H'){
board[i][j]='O';
}
}
}
}
//自定义方法,对于边界点为‘O’的元素进行左右上下的回溯
public void reserve(char[][] arr,int row,int col){
if(arr[row][col]=='O'){
arr[row][col]='H';
if(row>1){
reserve(arr,row-1,col);
}
if(col>1){
reserve(arr,row,col-1);
}
if(row<brow-1){
reserve(arr,row+1,col);
}
if(col<bcol-1){
reserve(arr,row,col+1);
}
}
}
}
附加迷宫问题的代码:
public class MiGong {
public static void main(String[] args) {
//创建二维数组,迷宫
int[][] map=new int[8][7];
//使用1表示围墙
for(int i=0;i<7;i++){
map[0][i]=1;
map[7][i]=1;
}
//左右置为1
for(int i=0;i<8;i++){
map[i][0]=1;
map[i][6]=1;
}
//设置挡板
map[3][1]=1;map[3][2]=1;
System.out.println("地图情况为");
for(int i=0;i<8;i++){
for(int j=0;j<7;j++){
System.out.print(map[i][j]+" ");
}
System.out.println();
}
//找到解决的路
setWay(map,1,1);
//输出地图
System.out.println("小球走过的路");
for(int i=0;i<8;i++){
for(int j=0;j<7;j++){
System.out.print(map[i][j]+" ");
}
System.out.println();
}
}
/*
* 1.map表示地图,i,j表示小球的出发位置
* 2.若小球能够到map[6][5]位置,能够到达返回true
* 3.约定1是围墙表示不能走,0表示该位置没有走,2表示通路可以走,3表示该位置走过但走不通
* 4.确定一个策略:先走哪个方向,规定:下----右-----上-----左,走不通再回溯
* */
public static boolean setWay(int[][] map,int i,int j){
if(map[6][5]==2){
return true;
}else{
if(map[i][j]==0){
//根据策略进行寻路
map[i][j]=2;
if(setWay(map,i+1,j)){//向下走
return true;
}else if(setWay(map,i,j+1)){//向右走
return true;
}else if(setWay(map,i-1,j)){//向上走
return true;
}else if(setWay(map,i,j-1)){//向左走
return true;
}else{//走不通
map[i][j]=3;
return false;
}
}else{//
return false;
}
}
}