130. Surrounded Regions

我是研究僧i 提交于 2020-08-08 20:46:59

题目:130. Surrounded Regions

题目地址: https://leetcode.com/problems/surrounded-regions/

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

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

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

解题思路

参考小土刀的答案 https://wdxtub.com/interview/14520604919872.html

Traverse from the border to the inside and mark all the 'O's that are not surrounded by 'X' as 'V' (visited).

转换一下思路,真的需要开辟一个map在存储访问信息吗?其实这个可以省掉的,既然已经知道连通区域必须至少一个元素是在四边,那么一开始直接从四边开始扫描就好了,所以无法connect到得元素都是应该被清除的。所以,算法如下:

  1. 从四条边上的O元素开始BFS,所有相连的O都赋个新值,比如‘Y’
  2. 扫描整个数组,所有现存的O元素全部置为X,所有Y元素置为O

BFS (queue).

举例来说,假设有如下的board

X X X X
X X O X
X O X X
X O X X

那么第一步,先找出四条边上的O的位置,然后对它们进行BFS,并将连通的O设为Y,如下所示:

X X X X
X X O X
X Y X X
X Y X X

第二步,在上图的基础上,将所有的O改为X,同时将Y改回为O,至此就完成了,如下图所示:

X X X X
X X X X
X O X X
X O X X

时间复杂度

因为最差的情况下,所有图上全为O,所以BFS的时候会遍历整个图,所以时间复杂度为O(n),其中n为图的元素的个数

最终实现

Java实现

import java.util.LinkedList;

// use BFS. The idea refers to https://wdxtub.com/interview/14520604919872.html
public class Solution {

    public void solve(char[][] board) {
        if (null == board) {
            return;
        }
        if (board.length == 0) {
            return;
        }
        printBoard(board);
        processBorderRegions(board);
        printBoard(board);
        resetBoard(board);
        printBoard(board);
    }

    private void processBorderRegions(char[][] board) {
        int rowNum = board.length;
        int colNum = board[0].length;
        // Step 1. do with the top edge
        for (int col = 0; col < colNum; col++) {
            if (board[0][col] == 'O') {
                bfsOnPosition(board, new Position(0, col));
            }
        }
        // Step 2. do with the bottom edge
        for (int col = 0; col < colNum; col++) {
            if (board[rowNum-1][col] == 'O') {
                bfsOnPosition(board, new Position(rowNum-1, col));
            }
        }
        // Step 3. do with the left edge
        for (int row = 0; row < rowNum; row++) {
            if (board[row][0] == 'O') {
                bfsOnPosition(board, new Position(row, 0));
            }
        }
        // Step 4. do with the right edge
        for (int row = 0; row < rowNum; row++) {
            if (board[row][colNum-1] == 'O') {
                bfsOnPosition(board, new Position(row, colNum-1));
            }
        }
    }

    private void bfsOnPosition(char[][] board, Position pos) {
        board[pos.row][pos.col] = 'Y';
        LinkedList<Position> queue = new LinkedList<>();
        queue.push(pos.up());
        queue.push(pos.down());
        queue.push(pos.left());
        queue.push(pos.right());
        while(!queue.isEmpty()) {
            pos = queue.poll();
            if (pos.row < 0 || pos.row >= board.length || pos.col < 0 || pos.col >= board[0].length) {
                continue;
            }
            if (board[pos.row][pos.col] == 'O') {
                board[pos.row][pos.col] = 'Y';
                queue.push(pos.up());
                queue.push(pos.down());
                queue.push(pos.left());
                queue.push(pos.right());
            }
        }
    }

    private void resetBoard(char[][] board) {
        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';
                } else if (board[i][j] == 'Y') {
                    board[i][j] = 'O';
                }
            }
        }
    }

    private void printBoard(char[][] board) {
        for (int i = 0; i < board.length; i++) {
            for (int j = 0; j < board[0].length; j++) {
                System.out.print(board[i][j]);
            }
            System.out.println();
        }
        System.out.println();
    }

    public static void main(String[] args) {
        char[][] board = new char[4][4];
        board[0][0] = 'X';
        board[0][1] = 'X';
        board[0][2] = 'X';
        board[0][3] = 'X';
        board[1][0] = 'X';
        board[1][1] = 'X';
        board[1][2] = 'O';
        board[1][3] = 'X';
        board[2][0] = 'X';
        board[2][1] = 'O';
        board[2][2] = 'X';
        board[2][3] = 'X';
        board[3][0] = 'X';
        board[3][1] = 'O';
        board[3][2] = 'X';
        board[3][3] = 'X';
        Solution solution = new Solution();
        solution.solve(board);
    }

    class Position {
        int row;
        int col;

        public Position(int row, int col) {
            this.row = row;
            this.col = col;
        }

        public int getCol() {
            return col;
        }

        public int getRow() {
            return row;
        }

        public void setCol(int col) {
            this.col = col;
        }

        public void setRow(int row) {
            this.row = row;
        }

        public Position up() {
            return new Position(row-1, col);
        }

        public Position down() {
            return new Position(row+1, col);
        }

        public Position left() {
            return new Position(row, col-1);
        }

        public Position right() {
            return new Position(row, col+1);
        }
    }

}

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!