• 130. 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

    链接:   http://leetcode.com/problems/surrounded-regions/

    题解:

    第一思路是从四条边的'O'开始做BFS,类似查找Connected Components或者图像处理里面的Region Grow。把找到的'O'标记为一个特殊符号比如'1'之类的。BFS结束后scan整个矩阵,把剩下的'O'变成'X','1'变回'O'。

    Time Complexity - O(mn), Space Complexity - O(mn)

    public class Solution {
        public void solve(char[][] board) {
            if(board == null || board.length == 0)
                return;            
            Queue<Node> q = new LinkedList<>();
               
            for(int i = 0; i < board.length; i++)  // first col
                if(board[i][0] == 'O')
                    q.offer(new Node(i, 0));
            
            for(int i = 0; i < board.length; i++) // last col
                if(board[i][board[0].length - 1] == 'O')
                    q.offer(new Node(i, board[0].length - 1));
            
            for(int i = 1; i < board[0].length - 1; i++)   // first row
                if(board[0][i] == 'O')
                    q.offer(new Node(0, i));
                    
            for(int i = 1; i < board[0].length - 1; i++)   // last row
                if(board[board.length - 1][i] == 'O')
                    q.offer(new Node(board.length - 1, i));
            
            while(!q.isEmpty()) {
                Node curNode = q.poll();
                if(curNode.row < 0 || curNode.row >= board.length || curNode.col >= board[0].length || curNode.col < 0)
                    continue;
                if(board[curNode.row][curNode.col] != 'O')
                    continue;
                board[curNode.row][curNode.col] = '|';                
                q.offer(new Node(curNode.row - 1, curNode.col));
                q.offer(new Node(curNode.row + 1, curNode.col));
                q.offer(new Node(curNode.row, curNode.col + 1));
                q.offer(new Node(curNode.row, curNode.col - 1));
            }       
            
            for(int i = 0; i < board.length; i++)
                for(int j = 0; j < board[0].length; j++)
                    if(board[i][j] == 'O')
                        board[i][j] = 'X';
             
            for(int i = 0; i < board.length; i++)
                for(int j = 0; j < board[0].length; j++)
                    if(board[i][j] == '|')
                        board[i][j] = 'O';
        }
        
         private class Node {
            public int row;
            public int col;
            public Node(int i, int j) {
                this.row = i;
                this.col = j;
            }
        }
    }

    代码有些长,有空一定要看一看discuss版简洁的解法,再来更新。 (看了一下好像大家写得也都比较长...算了先不更新了,Reference里的文章跟我的解法一样,不过说明更详细准备,挺好的)。

    题外话: 今天Work from home去洗牙,洗完牙以后医生说你最里面的大牙蛀了,裂了一条缝,需要补。长这么大第一次蛀牙,前些天总觉得不舒服,勤刷牙也无济于事。赶紧跟医生约好下周去补,拖延的话也许就要根管了。之后去Costco买了葡萄苹果和香蕉,家里还有三个桃子,可以靠吃水果度日。

    中午两点的时候兴业银行电面,法国人问了一些基本的OO问题,还有SQL问题,20多分钟就结束了,感觉双方兴趣都不大...对这些银行,我要奉行不主动,不拒绝,他们有兴趣我就面,就当熟悉简历和练口语了。

    二刷:

    重新写了一下,要先建立一个Node来保存坐标。然后使用一个Queue来对Node进行BFS。下面的写法里面有不少多余的计算,需要进一步好好剪枝。

    Java:

    Time Complexity - O(4mn), Space Complexity - O(4mn)

    public class Solution {
        public void solve(char[][] board) {         // BFS
            if (board == null || board.length == 0) return;
            Queue<Node> q = new LinkedList<>();
            int rowNum = board.length;
            int colNum = board[0].length;
            for (int i = 0; i < board.length; i++) {
                if (board[i][0] == 'O') q.offer(new Node(i, 0));
                if (board[i][colNum - 1] == 'O') q.offer(new Node(i, colNum - 1));
            }
            for (int j = 0; j < board[0].length; j++) {
                if (board[0][j] == 'O') q.offer(new Node(0, j));
                if (board[rowNum - 1][j] == 'O') q.offer(new Node(rowNum - 1, j));
            }
            
            while (!q.isEmpty()) {
                Node node = q.poll();
                int i = node.row, j = node.col;
                if (board[i][j] != 'O') continue;
                board[i][j] = '|';
                if (i - 1 >= 0 && board[i - 1][j] == 'O') q.offer(new Node(i - 1, j));
                if (i + 1 <= rowNum - 1 && board[i + 1][j] == 'O') q.offer(new Node(i + 1, j));
                if (j - 1 >= 0 && board[i][j - 1] == 'O') q.offer(new Node(i, j - 1));
                if (j + 1 <= colNum - 1 && board[i][j + 1] == 'O') q.offer(new Node(i, j + 1));
            }
            
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    if (board[i][j] == 'O') board[i][j] = 'X';       
                }
            }
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    if (board[i][j] == '|') board[i][j] = 'O';
                }
            }
        }
        
        private class Node {
            int row;
            int col;
            
            public Node(int i, int j) {
                this.row = i;
                this.col = j;
            }
        }
    }

    三刷:

    依然使用了BFS,简化了一下。速度仍然不是很快,大约9ms左右。需要进一步优化,或者尝试Union-Find和DFS。

    Java:

    Time Complexity - O(mn), Space Complexity - O(mn)

    public class Solution {
        public void solve(char[][] board) {         // BFS
            if (board == null || board.length == 0) return;
            Queue<int[]> q = new LinkedList<>();
            int rowNum = board.length;
            int colNum = board[0].length;
            for (int i = 0; i < rowNum; i++) {
                if (board[i][0] == 'O') q.offer(new int[] {i, 0});
                if (board[i][colNum - 1] == 'O') q.offer(new int[] {i, colNum - 1});
            }
            for (int j = 1; j < colNum - 1; j++) {
                if (board[0][j] == 'O') q.offer(new int[] {0, j});
                if (board[rowNum - 1][j] == 'O') q.offer(new int[] {rowNum - 1, j});
            }
            
            while (!q.isEmpty()) {
                int[] node = q.poll();
                int i = node[0], j = node[1];
                if (board[i][j] != 'O') continue;
                board[i][j] = '|';
                if (i - 1 >= 0 && board[i - 1][j] == 'O') q.offer(new int[] {i - 1, j});
                if (i + 1 <= rowNum - 1 && board[i + 1][j] == 'O') q.offer(new int[] {i + 1, j});
                if (j - 1 >= 0 && board[i][j - 1] == 'O') q.offer(new int[] {i, j - 1});
                if (j + 1 <= colNum - 1 && board[i][j + 1] == 'O') q.offer(new int[] {i, j + 1});
            }
            
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    if (board[i][j] == 'O') board[i][j] = 'X';       
                }
            }
            for (int i = 0; i < rowNum; i++) {
                for (int j = 0; j < colNum; j++) {
                    if (board[i][j] == '|') board[i][j] = 'O';
                }
            }
        }
    }

    Reference:

    https://leetcode.com/discuss/19805/my-java-o-n-2-accepted-solution

    https://leetcode.com/discuss/97838/share-my-4ms-improved-solution-beats-99-5%25

    https://leetcode.com/discuss/42445/a-really-simple-and-readable-c-solution%EF%BC%8Conly-cost-12ms

    https://leetcode.com/discuss/6285/solve-it-using-union-find

    https://leetcode.com/discuss/45746/9-lines-python-148-ms 

  • 相关阅读:
    3 聊天室
    freemaker分页模板
    [三]ajax重要属性
    [二]java运行原理
    [转]freemaker格式化日期
    [二]SpringMvc实践-注解
    win7下禁用ctrl alt del +上下左右键
    [一]初识SpringMVC
    Powerdesigner设置name与code不同时变化
    Ubuntu下缓冲器溢出攻击实验(可以看看问题分析)
  • 原文地址:https://www.cnblogs.com/yrbbest/p/4438754.html
Copyright © 2020-2023  润新知