LeetCode – Surrounded Regions (Java)

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

Analysis

This problem is similar to Number of Islands. In this problem, only the cells on the boarders can not be surrounded. So we can first merge those O’s on the boarders like in Number of Islands and replace O’s with ‘#’, and then scan the board and replace all O’s left (if any).

1. Depth-first Search

public void solve(char[][] board) {
    if(board == null || board.length==0) 
        return;
 
    int m = board.length;
    int n = board[0].length;
 
    //merge O's on left & right boarder
    for(int i=0;i<m;i++){
        if(board[i][0] == 'O'){
            merge(board, i, 0);
        }
 
        if(board[i][n-1] == 'O'){
            merge(board, i, n-1);
        }
    }
 
    //merge O's on top & bottom boarder
    for(int j=0; j<n; j++){
         if(board[0][j] == 'O'){
            merge(board, 0, j);
        }
 
        if(board[m-1][j] == 'O'){
            merge(board, m-1, j);
        }
    }
 
    //process the board
    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 merge(char[][] board, int i, int j){
    board[i][j] = '#';
 
    int[] dx = {-1, 0, 1, 0};
    int[] dy = {0, 1, 0, -1};
 
    for(int k=0; k<4; k++){
        int x = i+dx[k];
        int y = j+dy[k];
 
        if(x>=0 && x<board.length
          && y>=0 && y<board[0].length
          && board[x][y]=='O'){
            merge(board, x, y);
        }
    }
}

2. Breath-first Search

We can also use a queue to do breath-first search for this problem.

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);
        }
    }
 
    for(int j=0; j<n; 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);
        }
    }
 
    for(int i=0; i<m; i++){
        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]=='1'){
                board[i][j]='O';
            }
        }
    }
}
 
public void bfs(char[][] board, int o, int p){
    int m=board.length;
    int n=board[0].length;
 
    int index = o*n+p;
    LinkedList<Integer> queue = new LinkedList<Integer>();
    queue.offer(index);
    board[o][p]='1';
 
    while(!queue.isEmpty()){
        int top = queue.poll();
        int i=top/n;
        int j=top%n;
 
        if(i-1>=0 && board[i-1][j]=='O'){
            board[i-1][j]='1';
            queue.offer((i-1)*n+j);
        }
        if(i+1<m && board[i+1][j]=='O'){
            board[i+1][j]='1';
            queue.offer((i+1)*n+j);
        }
        if(j-1>=0 && board[i][j-1]=='O'){
            board[i][j-1]='1';
            queue.offer(i*n+j-1);
        }
        if(j+1<n && board[i][j+1]=='O'){
            board[i][j+1]='1';
            queue.offer(i*n+j+1);
        }
    }
}

6 thoughts on “LeetCode – Surrounded Regions (Java)”


  1. public class Solution {

    static int []dx = new int[]{0,-1,0,1};
    static int[]dy = new int[]{-1,0,1,0};

    static class Point{
    int x;
    int y;
    public Point(int a,int b){
    x = a;
    y = b;
    }
    }

    void bfs(char[][] board,int row,int col){

    int m = board.length;
    int n = board[0].length;

    board[row][col] = 'R';

    Queueq = new LinkedList();
    q.add(new Point(row,col));

    while(!q.isEmpty()){

    Point p = q.poll();

    for(int i=0; i=0 && x=0 && y<n && board[x][y]=='O'){
    q.add(new Point(x,y));
    board[x][y] = 'R';
    }

    }
    }

    }

    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++){
    for(int j=0; j<n; j++){

    if((i==0 || j==0 || j==n-1 || i==m-1)&&board[i][j]=='O'){
    //System.out.println(board[i][j]);
    bfs(board,i,j);
    }
    }
    }

    for(int i=0; i<m; i++){
    for(int j=0; j<n; j++){

    if(board[i][j]!='R'){
    board[i][j] = 'X';
    }else{
    board[i][j] = 'O';
    }

    }
    }

    }
    }

  2. To avoid stackoverflow error, avoid revisiting the boundaries again. This is done by using the if conditions. Below is the code (5 milli secs run time.)

    public class Solution {
    public void solve(char[][] board) {
    if (board.length == 0 || board[0].length == 0)
    return;
    if (board.length < 2 || board[0].length < 2)
    return;
    int m = board.length, n = board[0].length;
    //Any 'O' connected to a boundary can't be turned to 'X', so …
    //Start from first and last column, turn 'O' to '*'.
    for (int i = 0; i < m; i++) {
    if (board[i][0] == 'O')
    boundaryDFS(board, i, 0);
    if (board[i][n-1] == 'O')
    boundaryDFS(board, i, n-1);
    }
    //Start from first and last row, turn '0' to '*'
    for (int j = 0; j < n; j++) {
    if (board[0][j] == 'O')
    boundaryDFS(board, 0, j);
    if (board[m-1][j] == 'O')
    boundaryDFS(board, m-1, j);
    }
    //post-prcessing, turn 'O' to 'X', '*' back to 'O', keep 'X' intact.
    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';
    }
    }
    }

    private void boundaryDFS(char[][] board, int i, int j) {
    if (i board.length – 1 || j board[0].length – 1)
    return;
    if (board[i][j] == ‘O’)
    board[i][j] = ‘*’;
    if (i > 1 && board[i-1][j] == ‘O’)
    boundaryDFS(board, i-1, j);
    if (i 1 && board[i][j-1] == ‘O’)
    boundaryDFS(board, i, j-1);
    if (j < board[i].length – 2 && board[i][j+1] == 'O' )
    boundaryDFS(board, i, j+1);
    }
    }

Leave a Comment