【LeetCode】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

【DFS】

参考:http://blog.csdn.net/ojshilu/article/details/22600449#reply

两点:

1、从边缘入手,因为和边缘上的‘O’相连的‘O’都不会变,所以找出所有这样的‘O’,剩下的‘O’就是被完全包围的,把它们全部变为‘X’。

2、DFS过程中,暂时把遍历过的‘O‘用另外一个符号’#‘代替,最后把被包围的’O‘变成’X‘后,在把‘#’恢复成‘O’。

public class Solution {
    public void solve(char[][] board) {
        int row = board.length;
        if (row < 3) return;
        int col = board[0].length;
        if (col < 3) return;

        // first column and last column
        for (int i = 0; i < row; i++) {
            if (board[i][0] == 'O') {
                board[i][0] = '#';
                dfs(board, i, 0);
            }
            if (board[i][col - 1] == 'O') {
                board[i][col - 1] = '#';
                dfs(board, i, col - 1);
            }
        }

        // first row and last row
        for (int j = 0; j < col; j++) {
            if (board[0][j] == 'O') {
                board[0][j] = '#';
                dfs(board, 0, j);
            }
            if (board[row - 1][j] == 'O') {
                board[row - 1][j] = '#';
                dfs(board, row - 1, j);
            }
        }

        // change 'O' to 'X', restore '#' to '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';
                }
            }
        }
    }

    public void dfs(char[][] board, int i, int j) {
        int row = board.length;
        int col = board[0].length;

        // up
        if (i > 1 && board[i - 1][j] == 'O') {
            board[i - 1][j] = '#';
            dfs(board, i - 1, j);
        }
        // below
        if (i < row - 2 && board[i + 1][j] == 'O') {
            board[i + 1][j] = '#';
            dfs(board, i + 1, j);
        }
        // left
        if (j > 1 && board[i][j - 1] == 'O') {
            board[i][j - 1] = '#';
            dfs(board, i, j - 1);
        }
        // right
        if (j < col - 2 && board[i][j + 1] == 'O') {
            board[i][j + 1] = '#';
            dfs(board, i, j + 1);
        }
    }
}

注意,当行或列少于3时,不可能有被包围的‘O’。

这种思路简单易于理解,代码也很整洁,很适合初学者理解。

这个思路是从边缘向内部找连通的‘O’的,所以DFS时,就没必要在判断边缘上的字母了,因此DFS中,i 和 j 的条件为:i > 1, i < row - 2; j > 1, j < col - 2。(为什么?如果是 i = 1 时,那么 dfs(board, i - 1, j) 就是判断 [0, j] 了,而而边缘上的字母会被遍历判断的,这样就重复判断了,会导致栈溢出)。

DFS递归太深,容易栈溢出,这个代码可谓险过,最好还是用BFS。

【BFS】

参考:http://blog.sina.com.cn/s/blog_b9285de20101j1dt.html

public class Solution {
    char[][] board;
    int row;
    int col;
    Queue<Integer> queue = new LinkedList<Integer>();

    public void solve(char[][] board) {
        this.board = board;
        row = board.length;
        if (row < 3) return;
        col = board[0].length;
        if (col < 3) return;

        // traverse first column and last column
        for (int i = 0; i < row; i++) {
            bfs(i, 0);
            bfs(i, col - 1);
        }

        // traverse first row and last row
        for (int j = 0; j < col; j++) {
            bfs(0, j);
            bfs(row - 1, j);
        }

        // change 'O' to 'X', restore '#' to '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';
                }
            }
        }
    }

    public void bfs(int i, int j) {
        fill(i, j);
        while (!queue.isEmpty()) {
            int pos = queue.poll();
            int x = pos / col;
            int y = pos % col;

            fill(x - 1, y);
            fill(x + 1, y);
            fill(x, y - 1);
            fill(x, y + 1);
        }
    }

    public void fill(int i, int j) {
        if (i < 0 || j < 0 || i > row - 1 || j > col - 1) return;
        if (board[i][j] != 'O') return;
        queue.offer(i * col + j);
        board[i][j] = '#';
    }
}

DFS的实现是函数递归,BFS的实现是利用一个Queue。

关键的一点是,把 [i, j] 转化为 i * col + j 存储到Queue<Integer>里。

时间: 2024-10-28 19:49:27

【LeetCode】Surrounded Regions 解题报告的相关文章

LeetCode: Surrounded Regions 解题报告

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 XX O O XX X O XX O X XAfter running your function, the

LeetCode: Combination Sum 解题报告

Combination Sum Combination Sum Total Accepted: 25850 Total Submissions: 96391 My Submissions Question Solution Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C where the candidate numbers sums to T. The

LeetCode: Surrounded Regions [130]

[题目] 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 sh

[LeetCode]LRU Cache, 解题报告

题目 Design and implement a data structure for Least Recently Used (LRU) cache. It should support the following operations: get and set. get(key) - Get the value (will always be positive) of the key if the key exists in the cache, otherwise return -1.

[LeetCode] Surrounded Regions(DFS、BFS)

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

【LeetCode】Subsets 解题报告

[题目] Given a set of distinct integers, S, return all possible subsets. Note: Elements in a subset must be in non-descending order. The solution set must not contain duplicate subsets. For example, If S = [1,2,3], a solution is: [ [3], [1], [2], [1,2,

验证LeetCode Surrounded Regions 包围区域的DFS方法

在LeetCode中的Surrounded Regions 包围区域这道题中,我们发现用DFS方法中的最后一个条件必须是j > 1,如下面的红色字体所示,如果写成j > 0的话无法通过OJ,一直百思不得其解其中的原因,直到有网友告诉我说他验证了最后一个大集合在本地机子上可以通过,那么我也来验证看看吧. class Solution { public: void solve(vector<vector<char> >& board) { for (int i =

[leetcode]Surrounded Regions @ Python

原题地址:https://oj.leetcode.com/problems/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

LeetCode ZigZag Conversion 解题报告

对输入字符串,做蛇形变化,然后按行输出. https://oj.leetcode.com/problems/zigzag-conversion/ 例如:The string "PAYPALISHIRING"  的蛇形变化如下: P        A           H        N A   P   L    S     I     I   G Y         I            R 最后要求输出的就是:"PAHNAPLSIIGYIR" Write