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’是应该保留的?
 从上下左右四个边界往里走,凡是能碰到的
‘O’ ,都是跟边界接壤的,应该保留。
 思路:
 对于每一个边界上的‘O’作为起点,做若干次广度
优先搜索,对于碰到的‘O’,标记为其他某字符Y;
 最后遍历一遍整个地图,把所有的Y恢复成‘O’,把
所有现有的‘O’都改成‘X’。
public class Solution {
    static class Pair{
        public int first;
        public int second;
        public Pair(int f, int s){
            first = f;
            second = s;
        }
    }
 
    public static boolean  isValid(Pair p, char[][] board){
        int m= board.length;
        int n= board[0].length;
        int x = p.first;
        int y = p.second;
        if(x<0 || x>=m || y<0 ||y >=n || board[x][y]!='O')
             return false;
        return true;
    }
    
    public static List<Pair> state_extend(Pair pr, char[][] board){
        int m= board.length;
        int n= board[0].length;
        List<Pair> result = new ArrayList<Pair>();
        int x = pr.first;
        int y = pr.second;
        
        //上下左右
        Pair[] new_states = {new Pair(x-1,y),new Pair(x+1,y),
                              new Pair(x,y+1),new Pair(x,y-1)};
        
        for(int k =0; k<4; ++k){
            if(isValid(new_states[k],board)){
                board[new_states[k].first][new_states[k].second] ='+';
                result.add(new_states[k]);
            }
        }
        
        return result;
    }
    
    
    
    public void solve(char[][] board) {
        if(board.length ==0 )return ;
        
        //m,n赋值
         int m = board.length;
         int n = board[0].length;
        
        for(int i = 0; i<n; i++){
            bfs(board,0,i);
            bfs(board,m-1, i);
        }
        
        for(int j=1; j<m-1;j++){
            bfs(board,j,0);
            bfs(board,j,n-1);
        }
        
        for(int i=0; i<m;i++){
            for(int j =0; j<n; j++){
                if( board[i][j] =='O')board[i][j]='X';
                else if(board[i][j]=='+')
                    board[i][j]='O';
            }
        }//for
        
    }//solve
    
    
    public void  bfs(char[][] board, int i, int j){
       
        
        ArrayDeque<Pair> stack = new ArrayDeque<>();
        
        int m = board.length;
        int n = board[0].length;
        
        Pair p = new Pair(i,j);
        
        if(isValid(p,board)){
            board[i][j]='+';
            stack.push(p);
        }
        
       List<Pair> list = new ArrayList<Pair>();
        while(!stack.isEmpty()){
            Pair cur = stack.pop();
            list = state_extend(cur,board);
            
            for(Pair s: list) {
                stack.push(s);
            } 
        }
    }
    
    
}


 
网上方法,相对简洁
import java.util.LinkedList;
import java.util.List;

/**
 * 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.
 *
 * answer: 从上下左右四个边界找O,然后进行BFS,找到的都是要保留的,最后遍历一次修改字符即可。
 * 特别注意有一个用例 board 是空,所以进行判断否则会导致RE
 * 
 */
public class SurroundedRegions {
	class Point{
		int x,y;
		Point(int i,int j){x=i;y=j;}
	}
    public void solve(char[][] board) {
    	int m = board.length;
    	if(m == 0){		//判空防止 run-time error,不能和 n 一起判断
    		return;
    	}
    	int n = board[0].length;
    	if(n == 0){		//判空防止 run-time error
    		return;
    	}
    	for(int i=0;i<m;i++){
    		bfs(board,i,0);
    		bfs(board,i,n-1);
    	}
    	for(int j=0;j<n;j++){
    		bfs(board,0,j);
    		bfs(board,m-1,j);
    	}
    	
    	for(int i=0;i<m;i++){
    		for(int j=0;j<n;j++){
    			if(board[i][j] == 'O'){
    				board[i][j] = 'X';
    			}else if(board[i][j] == 'A'){
    				board[i][j] = 'O';
    			}
    		}
    	}

    }
    
    private void bfs(char[][] board,int x,int y){
    	if(board[x][y] != 'O'){
    		return ;
    	}
    	LinkedList<Point> queue = new LinkedList<>();
    	queue.add(new Point(x,y));
    	board[x][y] = 'A';
    	while(!queue.isEmpty()){
    		Point top = queue.poll();
    		int i = top.x;
    		int j = top.y;
    		addPoint(board,i-1,j,queue);
    		addPoint(board,i+1,j,queue);
    		addPoint(board,i,j-1,queue);
    		addPoint(board,i,j+1,queue);
    	}
    }
    
    private boolean addPoint(char[][] board,int x,int y,LinkedList<Point> queue){
    	if(x < 0 || x > board.length-1 || y < 0 || y > board[0].length-1 || board[x][y] != 'O'){
    		return false;
    	}else{
    	    queue.add(new Point(x,y));
    	    board[x][y] = 'A';
    		return true;
    	}
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值