我是靠谱客的博主 繁荣砖头,最近开发中收集的这篇文章主要介绍将矩阵中所有被X包围的O转换为X Surrounded Regions,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

为什么80%的码农都做不了架构师?>>>   hot3.png

问题:

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.

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

解决:

① 将被X包围的O都转化为X,边缘的O不算被包围,所以先对边界上的'O'遍历之后暂存为'*',非'*'的'O'即被'X'包围了。使用DFS。

class Solution { //栈溢出异常,因为方法调用太多
    public void solve(char[][] board) {
        if(board == null || board.length == 0) return;
        int m = board.length;
        int n = board[0].length;
        for (int i = 0;i < m ;i ++ ) {
            if(board[i][0] == 'O'){
                dfs(board,i,0);//将边缘的O替换为X
            }
            if (board[i][n - 1] == 'O') {
                dfs(board,i,n - 1);
            }
        }
        for (int j = 0;j < n ;j ++ ) {
            if (dfs[0][j] == 'O') {
                dfs(board,0,j);
            }
            if(board[m - 1][j] == 'O'){
                dfs(board,m - 1,j);
            }
        }
        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';
                }
            }
        }
    }
    public void dfs(char[][] board,int i,int j){
        if(i < 0 || i >= board.length || j < 0 || j >= board[0].length){
            return;
        }
        if(board[i][j] != 'O') return;
        board[i][j] = '*';
        dfs(board,i - 1,j);
        dfs(board,i + 1,j);
        dfs(board,i,j - 1);
        dfs(board,i,j + 1);
    }
}

② 在discuss中看到的,对上面的dfs方法进行优化。

class Solution { //4ms
    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;
        for (int i = 0;i < m ;i ++ ) {
            if(board[i][0] == 'O'){//替换边界上的‘O’
                dfs(board,i,0);
            }
        }
        if (n - 1 > 0) {//判断矩阵是否大于1列!若不是,就不需要额外的判断了,因为上面的判断已经实现了
            for (int i = 0;i < m ;i ++ ) {
                if (board[i][n - 1] == 'O') {
                    dfs(board,i,n - 1);
                }
            }
        }
        for (int i = 1;i < n - 1 ;i ++ ) {//i从1开始到n - 1结束,是为了跳过已经判断了的点
            if (board[0][i] == 'O') {
                dfs(board,0,i);
            }
        }
        if (n - 1 > 0) {//添加额外的判断,而且与上面的一样!!!,这是因为如果只有1列的话就不需要再判断了。
            for (int i = 1;i < n - 1 ;i ++ ) {
                if (board[m - 1][i] == 'O') {
                    dfs(board,m - 1,i);
                }
            }
        }
        for (int i = 1;i < n - 1 ;i ++ ) { //此处判断列是为了什么?经测试,可以不添加该部分,只是运行时间多了2ms
            dfs(board,0,i);
            if (m > 1) {
                dfs(board,m - 1,i);
            }
        }

        for (char[] rows : board ) { //修改被包围的'O'
            for (int i = 0;i < rows.length ;i ++ ) {
                if (rows[i] == 'O') {
                    rows[i] = 'X';
                }
            }
        }
        for (char[] rows : board) {//还原边界上的‘O’
            for (int i = 0;i < rows.length ;i ++ ) {
                if (rows[i] == '*') {
                    rows[i] = 'O';
                }
            }
        }
    }
    public void dfs(char[][] board,int i,int j){
        if (board[i][j] != 'O') {
            return;
        }
        board[i][j] = '*';
        if (i < board.length - 2) { //i行下面至少还有1行,由于该行没有被包围,所以继续往下判断
            dfs(board,i + 1,j);
        }
        if (i > 1) { //向上判断
            dfs(board,i - 1,j);
        }
        if (j > 1) { //向左判断
            dfs(board,i,j - 1);
        }
        if (j < board[0].length - 2) { //向右判断
            dfs(board,i,j + 1);
        }
    }//总之,就是将边界处的O改写之后,继续向内层判断是否有没被包含的O
}

③ 在discuss中看到,更好理解一点的优化方法。

class Solution { //5ms
    public void solve(char[][] board) {
        int m = board.length;
        if(m == 0) return;
        int n = board[0].length;
        for (int i = 0;i < m ;i ++ ) {
            dfs(board,i,0,m,n);//标记左边界
            if (n > 1) {
                dfs(board,i,n - 1,m,n);//标记右边界
            }
        }

        for (int j = 1;j + 1 < n ;j ++ ) {
            dfs(board,0,j,m,n);//标记上边界  
            if (m > 1) {
                dfs(board,m - 1,j,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';
                }
                if (board[i][j] == '*') {
                    board[i][j] = 'O';
                }
            }
        }
    }
    public void dfs(char[][] board,int i,int j,int m,int n){
        if (board[i][j] == 'O') {
            board[i][j] = '*';
            if (i > 1) {
                dfs(board,i - 1,j,m,n);
            }
            if (j > 1) {
                dfs(board,i,j - 1,m,n);
            }
            if (i + 1 < m) {
                dfs(board,i + 1,j,m,n);
            }
            if (j + 1 < n) {
                dfs(board,i, j + 1,m,n);
            }
        }
    }
}

③ BFS遍历

class Solution { //10ms
    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;
        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);
            }
        }
        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);
            }
        }
        for (int i = 0;i < m ;i ++ ) {
            for (int j = 0;j < n ;j ++ ) {
                if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
                if (board[i][j] == '*') {
                    board[i][j] = 'O';
                }
            }
        }
    }
    public void bfs(char[][] board,int i,int j){
        int m = board.length;
        int n = board[0].length;
        int index = i * n + j; //计算当前点的个数
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(index);
        board[i][j] = '*';
        while(! queue.isEmpty()){
            int top = queue.poll();
            int x = top / n; 
            int y = top % n;

            if(x - 1 >= 0 && board[x - 1][y] == 'O'){
                board[x - 1][y] = '*';
                queue.offer((x - 1) * n + y);
            }
            if (x + 1 < m && board[x + 1][y] == 'O') {
                board[x + 1][y] = '*';
                queue.offer((x + 1) * n + y);
            }
            if (y - 1 >= 0 && board[x][y - 1] == 'O') {
                board[x][y - 1] = '*';
                queue.offer(x * n + y - 1);
            }
            if (y + 1 < n && board[x][y + 1] == 'O') {
                board[x][y + 1] = '*';
                queue.offer(x * n + y + 1);
            }
        }
    }
}

转载于:https://my.oschina.net/liyurong/blog/1544484

最后

以上就是繁荣砖头为你收集整理的将矩阵中所有被X包围的O转换为X Surrounded Regions的全部内容,希望文章能够帮你解决将矩阵中所有被X包围的O转换为X Surrounded Regions所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部