[letecode Java] Surrounded Regions

来源:互联网 发布:cog数据库官网 编辑:程序博客网 时间:2024/06/14 11:51

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 XX O O XX X O XX O X X

After running your function, the board should be:

X X X XX X X XX X X XX O X X

分析:

解法一:

典型的BFS题目。遍历每个字符,如果是“O”,则从当前字符开始BFS遍历,如果周围也是“O”则加入当前遍历的队列,知道遍历完所有相邻的“O”,于此同时,判断每个O是否是被包围的,只有由一个O是没有被包围的,则当前遍历的O的集合都是没有被包围的,因为这些O都是相连的。

 public void solve(char[][] board) {
        //存储'O'
        Queue<Integer> queue=new LinkedList<>();
        
        if(board==null||board.length==0||board[0].length==0)
            return;
        int m=board.length;
        int n=board[0].length;
        boolean[][] visited=new boolean[m][n];
        int[][] dir={{1,0},{-1,0},{0,1},{0,-1}};
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                //以下是标准的BFS搜索,用visitedPoints记录访问的O
                if(board[i][j]=='O'&&(!visited[i][j])){
                    boolean surround=true;
                    queue.add(i*n+j);
                    visited[i][j]=true;
                    //存储相邻的'O'的位置
                    List<Integer> visitedPoints=new ArrayList<>();
                    while(queue.size()>0){
                        int point=queue.poll();
                        visitedPoints.add(point);
                        int x=point/n;
                        int y=point%n;
                        for(int k=0;k<4;k++){//搜索上下左右
                            int nextx=x+dir[k][0];
                            int nexty=y+dir[k][1];
                            if(nextx>=0 && nextx<m && nexty>=0 && nexty<n){
                                if(board[nextx][nexty]=='O' &&(!visited[nextx][nexty])){
                                    queue.add(nextx*n+nexty);
                                }
                                visited[nextx][nexty]=true;
                            }else{
                                surround=false;
                            }
                        }
                    }
                    //如果当前遍历到的O都是被包围的
                    if(surround){
                        for(int p:visitedPoints){
                            board[p/n][p%n]='X';
                        }
                    }
                }
            }
        }
    }

解法二:
/**
     * 只从边界BFS,将所有遍历到的O变为V,表示已经访问过,且与边界相通,之后再次遍历矩阵,将剩余的O(被包围的)变为X,将V变回O
     **/
    public void solve(char[][] board) {
        if(board==null||board.length==0||board[0].length==0)
            return;
        int m=board.length;
        int n=board[0].length;
        int[][] dir={{-1,0},{1,0},{0,-1},{0,1}};
        for(int i=0;i<n;i++){
            bfs(board,0,i,dir,m,n);
            bfs(board,m-1,i,dir,m,n);
        }
        for(int i=0;i<m;i++){
            bfs(board,i,0,dir,m,n);
            bfs(board,i,n-1,dir,m,n);
        }
        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]=='V')
                    board[i][j]='O';
            }
        }
    }
    
    private void bfs(char[][] board,int x,int y,int[][] dir,int m,int n){
        if(board[x][y]!='O')
            return ;
        Queue<Integer> queue=new LinkedList<>();
        queue.add(x*n+y);
        board[x][y]='V';
        while(queue.size()>0){
            int point=queue.poll();
            for(int i=0;i<4;i++){
                int nextx=point/n+dir[i][0];
                int nexty=point%n+dir[i][1];
                if(nextx>=0 &&nextx<m &&nexty>=0 &&nexty<n &&board[nextx][nexty]=='O'){
                    board[nextx][nexty]='V';
                    queue.add(nextx*n+nexty);
                }
            }
        }
    }
}
原文链接:http://www.acmerblog.com/leetcode-surrounded-regions-6171.html
0 0
原创粉丝点击