Leetcode 130. Surrounded Regions

来源:互联网 发布:在淘宝点击卖家没反应 编辑:程序博客网 时间:2024/05/16 01:53

130. Surrounded Regions

Total Accepted: 53520 Total Submissions: 330327 Difficulty: Medium

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 X

After running your function, the board should be:

X X X XX X X XX X X XX O X X


思路很清晰,但是不知道为啥debug非常久的一题。


思路:

按照题意,如果一个O或者一片O周围都是X的话,那么就应该把这些O换成X。也就是说,这些O必须能连到边界的O。

因此可以按照BFS思想,从4条边开始,往里走,如果是X,则不处理。否则调用BFS算法,将从该O课到达的所有O置为#,这样最后再遍历一遍图,剩下的O即是没有连接到外围的O,这些O应该被置为X。而为#的O是安全的,将它们换回O即可。


思路非常简单,说说自己coding过程中的碰到的问题吧:

1.一开始想着用recursive做,不过好像无论怎么弄都会stackoverflow。

2.一开始想着遍历4条边,如果是O,那么就传递下一个位置去做。这个当然是错误的,因为最终思想是mark出可以连通的O,如果这样,边界的O就都被换成X了。

3.最容易错的一点是:就算用了BFS,也应该是置#和入队在同一时候做。比如下面这个例子,入队之后立马将其置#,这样每个元素不会重复拿出来判断。

void bfs(char[][] board, int row, int col){        if(board[row][col]!='O') return;        LinkedList<coordinate> queue = new LinkedList<coordinate>();        coordinate c = new coordinate(row, col);        queue.add(c);        board[row][col]='#';                while(queue.size()!=0){            coordinate cur = queue.poll();            if(cur.x>=1 && board[cur.x-1][cur.y]=='O') {                queue.add(new coordinate(cur.x-1, cur.y)); board[cur.x-1][cur.y]='#';            }                        if(cur.y>=1 && board[cur.x][cur.y-1]=='O') {                queue.add(new coordinate(cur.x, cur.y-1)); board[cur.x][cur.y-1]='#';            }                        if(cur.x<=board.length-2 && board[cur.x+1][cur.y]=='O') {                queue.add(new coordinate(cur.x+1, cur.y)); board[cur.x+1][cur.y]='#';            }                        if(cur.y<=board[0].length-2 && board[cur.x][cur.y+1]=='O') {                queue.add(new coordinate(cur.x, cur.y+1)); board[cur.x][cur.y+1]='#';            }        }    }

反例就是我写的例子,提示TLE:

void bfs(char[][] board, int row, int col){        if(board[row][col]!='O') return;        LinkedList<coordinate> queue = new LinkedList<coordinate>();        coordinate c1 = new coordinate(row, col);        queue.add(c1);                while(!queue.isEmpty()){            coordinate cur = queue.poll();            board[cur.x][cur.y]='#';            if(cur.x>=1 && board[cur.x-1][cur.y]=='O') queue.add(new coordinate(cur.x-1, cur.y));            if(cur.y>=1 && board[cur.x][cur.y-1]=='O') queue.add(new coordinate(cur.x, cur.y-1));            if(cur.x<=board.length-2 && board[cur.x+1][cur.y]=='O') queue.add(new coordinate(cur.x+1, cur.y));            if(cur.y<=board[0].length-2 && board[cur.x][cur.y+1]=='O') queue.add(new coordinate(cur.x, cur.y+1));        }    }


区别就是先入队了,然后每次取出一个再置#,大概是有很多重复case。

void bfs(char[][] board, int row, int col){        if(board[row][col]!='O') return;        LinkedList<coordinate> queue = new LinkedList<coordinate>();        coordinate c1 = new coordinate(row, col);        queue.add(c1);                while(!queue.isEmpty()){            coordinate cur = queue.poll();            board[cur.x][cur.y]='#';            if(cur.x>=1 && board[cur.x-1][cur.y]=='O') queue.add(new coordinate(cur.x-1, cur.y));            if(cur.y>=1 && board[cur.x][cur.y-1]=='O') queue.add(new coordinate(cur.x, cur.y-1));            if(cur.x<=board.length-2 && board[cur.x+1][cur.y]=='O') queue.add(new coordinate(cur.x+1, cur.y));            if(cur.y<=board[0].length-2 && board[cur.x][cur.y+1]=='O') queue.add(new coordinate(cur.x, cur.y+1));        }    }

最终的代码:

public class Solution {    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;        if(m<=1 || n<=1) return;                for(int j=0; j<n; j++){            bfs(board, 0, j);            bfs(board, m-1, j);        }                for(int i=0; i<m-1; i++){            bfs(board, i, 0);            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';                else if(board[i][j]=='#') board[i][j]='O';            }        }        return;    }        void bfs(char[][] board, int row, int col){        if(board[row][col]!='O') return;        LinkedList<coordinate> queue = new LinkedList<coordinate>();        coordinate c = new coordinate(row, col);        queue.add(c);        board[row][col]='#';                while(queue.size()!=0){            coordinate cur = queue.poll();            if(cur.x>=1 && board[cur.x-1][cur.y]=='O') {                queue.add(new coordinate(cur.x-1, cur.y)); board[cur.x-1][cur.y]='#';            }                        if(cur.y>=1 && board[cur.x][cur.y-1]=='O') {                queue.add(new coordinate(cur.x, cur.y-1)); board[cur.x][cur.y-1]='#';            }                        if(cur.x<=board.length-2 && board[cur.x+1][cur.y]=='O') {                queue.add(new coordinate(cur.x+1, cur.y)); board[cur.x+1][cur.y]='#';            }                        if(cur.y<=board[0].length-2 && board[cur.x][cur.y+1]=='O') {                queue.add(new coordinate(cur.x, cur.y+1)); board[cur.x][cur.y+1]='#';            }        }    }        class coordinate{        int x;        int y;        coordinate(int x, int y){            this.x = x;            this.y = y;        }    }}


0 0