zoukankan      html  css  js  c++  java
  • lintcode:被围绕的区域

    被围绕的区域

    给一个二维的矩阵,包含 'X' 和 'O', 找到所有被 'X' 围绕的区域,并用 '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
    X O X X

    解题
    参考岛屿的个数 然而我还是写不出来
    programcreek 有下面的一段话:

    This problem is similar to Number of Islands. In this problem, only the cells on the
    boarders can not be surrounded. So we can first merge those O’s on the boarders like
    in Number of Islands and replace O’s with ’#’, and then scan the board and replace all
    O’s left (if any)

    先将边界中联通的O换成*,这里利用深度优先

    最后遍历数组,O->X  *->O,每个位置值遍历一次,不会出现混乱 

    public class Solution {
        /**
         * @param board a 2D board containing 'X' and 'O'
         * @return void
         */
        public void surroundedRegions(char[][] board) {
            // Write your code here
            if(board == null || board.length == 0|| board[0].length == 0)
                return ;
            int row = board.length;
            int col = board[0].length;
            for(int i =0;i< row;i++){
                if(board[i][0] == 'O')
                    merge(board,i,0);
                if(board[i][col-1] == 'O')
                    merge(board,i,col-1);
            }
            for(int j =0;j< col;j++){
                if(board[0][j] == 'O')
                    merge(board,0,j);
                if(board[row-1][j] == 'O')
                    merge(board,row-1,j);
            }
            // O->X  *->O
            for(int i=0;i<row;i++){
                for(int j=0; j<col; j++){
                    if(board[i][j] == 'O'){
                        board[i][j] = 'X';
                    }else if(board[i][j] == '*'){
                        board[i][j] = 'O';
                    }
                }
            }
        }
        // 将边界联通的O 换成 * 
        public void merge(char[][] board,int row,int col){
            if(row<0 || col<0 || row>= board.length || col>= board[0].length)
                return;
            if(board[row][col] != 'O')
                return;
            board[row][col] = '*';
            merge(board,row,col+1);
            merge(board,row+1,col);
            merge(board,row-1,col);
            merge(board,row,col-1);
        }
    }
    This solution causes java.lang.StackOverflowError, because for a large board, too many method calls are pushed to the stack and causes the overflow.

    programcreek 中又给了一个广度优先的算法

    比较复杂,先把程序复杂过来

    public class Solution {
        // use a queue to do BFS
        private Queue<Integer> queue = new LinkedList<Integer>();
     
        public void solve(char[][] board) {
            if (board == null || board.length == 0)
                return;
     
            int m = board.length;
            int n = board[0].length;
     
            // merge O's on left & right boarder
            for (int i = 0; i < m; i++) {
                if (board[i][0] == 'O') {
                    bfs(board, i, 0);
                }
     
                if (board[i][n - 1] == 'O') {
                    bfs(board, i, n - 1);
                }
            }
     
            // merge O's on top & bottom boarder
            for (int j = 0; j < n; j++) {
                if (board[0][j] == 'O') {
                    bfs(board, 0, j);
                }
     
                if (board[m - 1][j] == 'O') {
                    bfs(board, m - 1, j);
                }
            }
     
            // process the board
            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';
                    }
                }
            }
        }
     
        private void bfs(char[][] board, int i, int j) {
            int n = board[0].length;
     
            // fill current first and then its neighbors
            fillCell(board, i, j);
     
            while (!queue.isEmpty()) {
                int cur = queue.poll();
                int x = cur / n;
                int y = cur % n;
     
                fillCell(board, x - 1, y);
                fillCell(board, x + 1, y);
                fillCell(board, x, y - 1);
                fillCell(board, x, y + 1);
            }
        }
     
        private void fillCell(char[][] board, int i, int j) {
            int m = board.length;
            int n = board[0].length;
            if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O')
                return;
     
            // add current cell is queue & then process its neighbors in bfs
            queue.offer(i * n + j);
            board[i][j] = '#';
        }
    }

    update

    public class Solution {
        /**
         * @param board a 2D board containing 'X' and 'O'
         * @return void
         */
        public void surroundedRegions(char[][] board) {
            // Write your code here
            if(board == null || board.length == 0 || board[0].length ==0)
                return;
            int row = board.length;
            int col = board[0].length;
            // 边界的 O 变为 P 
            for(int i =0;i<row;i++){ 
                if(board[i][0] == 'O')
                    dfs(board,i,0,row,col);
                if(board[i][col-1] == 'O')
                    dfs(board,i,col-1,row,col);
            }
            for(int j=0;j<col;j++){
                if(board[0][j] == 'O')
                    dfs(board,0,j,row,col);
                if(board[row-1][j] == 'O')
                    dfs(board,row-1,j,row,col);
                    
            }
            // 中间的 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';
                }
            }
            // P 还原 O
            for(int i=0;i<row;i++){
                for(int j=0;j<col;j++){
                    if(board[i][j] == 'P')
                        board[i][j] = 'O';
                }
            }
        }
        // 将 ij 周围的 O - > P
        
        public void dfs(char[][] board,int i,int j,int row,int col){
            if(i<0 ||i>=row ||j<0 ||j>=col)
                return ;
            if(board[i][j]=='O'){
                board[i][j] ='P';
                dfs(board,i+1,j,row,col);
                dfs(board,i,j+1,row,col);
                dfs(board,i-1,j,row,col);
                dfs(board,i,j-1,row,col);
            }
        }
    }
  • 相关阅读:
    黄聪:PowerPoint设计编辑动画的时候图层隐藏和显示问题
    黄聪:如何在Windows上安裝BeautifulSoup
    黄聪:二、如何通过URL获取其他网页源代码内容(火狐插件扩展开发教程)
    黄聪:2006 MySQL server has gone away错误,最大值溢出解决办法 mysql max_allowed_packet 查询和修改
    黄聪:解决python中文处理乱码,先要弄懂“字符”和“字节”的差别
    ExtAspNet v2.2.1
    ExtAspNet v2.3.2
    [原创]全球首款不使用ViewState的Asp.Net2.0控件库
    [原创]从程序员角度分析安徽电信HTTP劫持的无耻行径 草根的暂时胜利
    [原创]从程序员角度分析安徽电信HTTP劫持的无耻行径 – 之深度分析
  • 原文地址:https://www.cnblogs.com/theskulls/p/5350113.html
Copyright © 2011-2022 走看看