牛客网刷题之数组

题目描述:
现在有一个仅包含‘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;
			}
		}
		
	}
	
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值