[LeetCode131]Surrounded Region

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:

Search is a good way to solve this problem!
First and easy thought might, scan all the element, if meets 'O', looking for a path to the boundary, if not exist, put it to 'X'. To look for the path, if all the four directions all have no way out, this element has no way out. The DFS can be used. See code(small case) below. Actually, it only cannot pass the last big test case (where 250x250 matrix is provided).

However, it will not pass the big test, because the complexity is too high. One common thought is to use BFS instead of DFS, which use more space, but less time.

So how BFS is conducted, we can think from out to inside. Because the boundary 'O' are definitely "live" (have a path out) element, so, we BFS from each 'O' in the boundary, mark all its four directions (where is also 'O') as "live". If you think here, you almost done, the standard BFS using a queue (here I use vector for simplicity) can solve the problem. Last step is to flip "O" to "X" because there is no way out, and flip "Y"(live) to "O", because it has a path out. See code (big case) for details. All the test cases are passed

已经知道连通区域必须至少一个元素是在四边,那么一开始直接从四边开始扫描就好了,所以无法connect到得元素都是应该被清除的。所以,算法如下:
1. 从四条边上的O元素开始BFS,所有相连的O都赋个新值,比如‘Y’
2. 扫描整个数组,所有现存的O元素全部置为X,所有Y元素置为O

Java

public void solve(char[][] board) {
        ArrayList<Integer> xIndex = new ArrayList<>();
	    ArrayList<Integer> yIndex = new ArrayList<>();
	    int row = board.length;
	    if(row == 0) return;
	    int col = board[0].length;
	    if(col ==0) return;
	    //record the element in the boundary that are o
	    for(int i=0;i<row;i++){
	        if(board[i][0]=='O'){
	            xIndex.add(i);
	            yIndex.add(0);
	        }
	        if(board[i][col-1]=='O'){
	            xIndex.add(i);
	            yIndex.add(col-1);
	        }
	    }
	    for(int j=1;j<col-1;j++){
	        if(board[0][j]=='O'){
	            xIndex.add(0);
	            yIndex.add(j);
	        }
	        if(board[row-1][j]=='O'){
	            xIndex.add(row-1);
	            yIndex.add(j);
	        }
	    }
	    int k=0;
	    while(k<xIndex.size()){//detect 'o' path form the edge
	        int x = xIndex.get(k);
	        int y = yIndex.get(k);
	        board[x][y] = 'Y';
	        if(x>0 && board[x-1][y]=='O'){//up
	            xIndex.add(x-1);
	            yIndex.add(y);
	        }
	        if(x<row-1 && board[x+1][y]=='O'){//down
	            xIndex.add(x+1);
	            yIndex.add(y);
	        }
	        if(y>0 && board[x][y-1]=='O'){//left
	            xIndex.add(x);
	            yIndex.add(y-1);
	        }
	        if(y<col-1 && board[x][y+1]=='O'){//right
	            xIndex.add(x);
	            yIndex.add(y+1);
	        }
	        k++;
	    }
	    for(int i=0;i<row;i++){
	        for(int j=0;j<col;j++){
	            if(board[i][j]=='O') board[i][j] = 'X';//should first change to X
	            if(board[i][j]=='Y') board[i][j] = 'O';
	        }
	    }
    }
c++

void solve(vector<vector<char>> &board) {
        vector<int> xIndex;
    vector<int> yIndex;
    int row = board.size();
    if(row == 0) return;
    int col = board[0].size();
    if(col ==0) return;
    //record the element in the bounary that are o
    for(int i=0;i<row;i++){
        if(board[i][0]=='O'){
            xIndex.push_back(i);
            yIndex.push_back(0);
        }
        if(board[i][col-1]=='O'){
            xIndex.push_back(i);
            yIndex.push_back(col-1);
        }
    }
    for(int j=1;j<col-1;j++){
        if(board[0][j]=='O'){
            xIndex.push_back(0);
            yIndex.push_back(j);
        }
        if(board[row-1][j]=='O'){
            xIndex.push_back(row-1);
            yIndex.push_back(j);
        }
    }
    int k=0;
    while(k<xIndex.size()){//detect 'o' path form the edge
        int x = xIndex[k];
        int y = yIndex[k];
        board[x][y] = 'Y';
        if(x>0 && board[x-1][y]=='O'){//up
            xIndex.push_back(x-1);
            yIndex.push_back(y);
        }
        if(x<row-1 && board[x+1][y]=='O'){//down
            xIndex.push_back(x+1);
            yIndex.push_back(y);
        }
        if(y>0 && board[x][y-1]=='O'){//left
            xIndex.push_back(x);
            yIndex.push_back(y-1);
        }
        if(y<col-1 && board[x][y+1]=='O'){//right
            xIndex.push_back(x);
            yIndex.push_back(y+1);
        }
        k++;
    }
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            if(board[i][j]=='O') board[i][j] = 'X';//should first change to X
            if(board[i][j]=='Y') board[i][j] = 'O';
        }
    }
    }




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值