LeetCode 130 - Surrounded Regions


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

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).
http://blog.csdn.net/linhuanmars/article/details/22904855
这个题目用到的方法是图形学中的一个常用方法:Flood fill算法,其实就是从一个点出发对周围区域进行目标颜色的填充。背后的思想就是把一个矩阵看成一个图的结构,每个点看成结点,而边则是他上下左右的相邻点,然后进行一次广度或者深度优先搜索。

每个结点改变次数不会超过一次,因而是O(m*n)的复杂度.空间上就是递归栈(深度优先搜索)或者是队列(广度优先搜索)的空间,同时存在的空间占用不会超过O(m+n)(以广度优先搜索为例,每次队列中的结点虽然会往四个方向拓展,但是事实上这些结点会有很多重复,假设从中点出发,可以想象最大的扩展不会超过一个菱形,也就是n/2*2+m/2*2=m+n,所以算法的空间复杂度是O(m+n))。
  •  DFS find all 'O' not surrounded by 'X' (at or connected to the edge of the board ) and changed to '#'
  •  Flip the remain 'O' into X
  •  Flip the '#' back to 'O'
DFS: O(n^2)
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){
    if(i<0 || i>=board.length || j<0 || j>=board[0].length) 
        return;
 
    if(board[i][j] != 'O')
        return;
 
    board[i][j] = '#';
 
    merge(board, i-1, j);
    merge(board, i+1, j);
    merge(board, i, j-1);
    merge(board, i, j+1);
}
https://leetcode.com/discuss/59652/java-boundary-turning-solution-simple-clean-code-commented

http://huntfor.iteye.com/blog/2082657
Code would be cleaner if we check condition in base condition
http://bangbingsyb.blogspot.com/2014/11/leetcode-surrounded-regions.html
Iterative DFS:
    void solve(vector<vector<char>> &board) {
        if(board.size()<3 || board[0].size()<3) return;
        fillBorders(board, 'O', 'Y');
        replace(board, 'O', 'X');
        fillBorders(board, 'Y', 'O');
    }
    void fill(vector<vector<char>> &board, int i, int j, char target, char c) {
        int m = board.size(), n = board[0].size();
        if(i<0 || j<0 || i>=m || j>=n || board[i][j]!=target) return;
        stack<pair<int,int>> s;
        s.push(make_pair(i,j));
        
        while(!s.empty()) {
            i = s.top().first;
            j = s.top().second;
            s.pop();
            board[i][j] = c;
            if(i>0 && board[i-1][j]==target) s.push(make_pair(i-1,j));
            if(i<m-1 && board[i+1][j]==target) s.push(make_pair(i+1,j));
            if(j>0 && board[i][j-1]==target) s.push(make_pair(i,j-1));
            if(j<n-1 && board[i][j+1]==target) s.push(make_pair(i,j+1));
        }
    }
    
    void fillBorders(vector<vector<char>> &board, char target, char c) {
        int m = board.size(), n = board[0].size();
        for(int i=0; i<m; i++) {
            if(board[i][0]==target) fill(board, i, 0, target, c);
            if(board[i][n-1]==target) fill(board, i, n-1, target, c);
        }
        
        for(int j=1; j<n-1; j++) {
            if(board[0][j]==target) fill(board, 0, j, target, c);
            if(board[m-1][j]==target) fill(board, m-1, j, target, c);
        }
    }
    
    
    void replace(vector<vector<char>> &board, char target, char c) {
        int m = board.size(), n = board[0].size();
        for(int i=0; i<m; i++) {
            for(int j=0; j<n; j++) {
                if(board[i][j]==target)
                    board[i][j] = c;
            }
        }
    }

https://discuss.leetcode.com/topic/6496/my-java-o-n-2-accepted-solution
public void markUnflippable(char[][] board, int r, int c) {
    int[] dirX = {-1,0,1,0};
    int[] dirY = {0,1,0,-1};
    ArrayDeque<Pair> stack = new ArrayDeque<>();
    stack.push(new Pair(r,c));
    while(!stack.isEmpty()) {
        Pair p = stack.pop();
        board[p.first][p.second] = 'U';
        for(int i = 0; i < dirX.length; ++i) {
            if(p.first + dirX[i] >= 0 && p.first + dirX[i] < board.length && p.second + dirY[i] >= 0 && p.second +dirY[i] < board[p.first + dirX[i]].length && board[p.first+dirX[i]][p.second+dirY[i]] == 'O') {
                stack.push(new Pair(p.first+dirX[i],p.second+dirY[i]));
            }
        }
    }
}

BFS:
https://shawnlincoding.wordpress.com/2015/03/21/surrounded-regions/
https://leetcode.com/discuss/19805/my-java-o-n-2-accepted-solution
接下来我们看看这个题如何用Flood fill算法来解决。首先根据题目要求,边缘上的’O’是不需要填充的,所以我们的办法是对上下左右边缘做Flood fill算法,把所有边缘上的’O’都替换成另一个字符,比如’#’。接下来我们知道除去被我们换成’#’的那些顶点,剩下的所有’O’都应该被替换成’X’,而’#’那些最终应该是还原成’O’,如此我们可以做最后一次遍历,然后做相应的字符替换就可以了。复杂度分析上,我们先对边缘做Flood fill算法,因为只有是’O’才会进行,而且会被替换成’#’,所以每个结点改变次数不会超过一次,因而是O(m*n)的复杂度,最后一次遍历同样是O(m*n),所以总的时间复杂度是O(m*n)。空间上就是递归栈(深度优先搜索)或者是队列(广度优先搜索)的空间,同时存在的空间占用不会超过O(m+n)(以广度优先搜索为例,每次队列中的结点虽然会往四个方向拓展,但是事实上这些结点会有很多重复,假设从中点出发,可以想象最大的扩展不会超过一个菱形,也就是n/2*2+m/2*2=m+n,所以算法的空间复杂度是O(m+n)
    public void solve(char[][] board) {
        if(board == null || board.length == 0){
            return;
        }
        int m = board.length, n = board[0].length;
        for(int i = 0; i < m; i++){
            helper(board, i, 0);
            helper(board, i, n - 1);
        }
        for(int i = 0; i < n; i++){
            helper(board, 0, i);
            helper(board, m - 1, i);
        }
        for(int i = 0; i < m; i++){
            for(int j = 0; j < n; j++){
                if(board[i][j] == '#'){
                    board[i][j] = 'O';
                }else if(board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
            }
        }
    }
     
    private void helper(char[][] board, int i, int j){
        if(board[i][j] != 'O'){
            return;
        }
        int m = board.length, n = board[0].length;
        board[i][j] = '#';
        Queue<Integer> queue = new LinkedList<Integer>();
        queue.offer(i * n + j);
        while(!queue.isEmpty()){
            int pos = queue.poll();
            int row = pos / n, col = pos % n;
            if(row > 0 && board[row - 1][col] == 'O'){
                queue.offer((row - 1) * n + col);
                board[row - 1][col] = '#';
            }
            if(row < m - 1 && board[row + 1][col] == 'O'){
                queue.offer((row + 1) * n + col);
                board[row + 1][col] = '#';
            }
            if(col > 0 && board[row][col - 1] == 'O'){
                queue.offer(row * n + col - 1);
                board[row][col - 1] = '#';
            }
            if(col < n - 1 && board[row][col + 1] == 'O'){
                queue.offer(row * n + col + 1);
                board[row][col + 1] = '#';
            }
        }         
    }
 // use a queue to do BFS
 private Queue<Integer> queue = new LinkedList<Integer>();
 
 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') {
    bfs(board, i, 0);
   }
 
   if (board[i][n - 1] == 'O') {
    bfs(board, i, n - 1);
   }
  }
   // merge O's on top & bottom boarder
  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);
   }
  }
  // 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';
    }
   }
  }
 }
  private void bfs(char[][] board, int i, int j) {
  int n = board[0].length;
 
  // fill current first and then its neighbors
  fillCell(board, i, j);
 
  while (!queue.isEmpty()) {
   int cur = queue.poll();
   int x = cur / n;
   int y = cur % n;
 
   fillCell(board, x - 1, y);
   fillCell(board, x + 1, y);
   fillCell(board, x, y - 1);
   fillCell(board, x, y + 1);
  }
 }
 private void fillCell(char[][] board, int i, int j) {
  int m = board.length;
  int n = board[0].length;
  if (i < 0 || i >= m || j < 0 || j >= n || board[i][j] != 'O')
   return;
 
  // add current cell is queue & then process its neighbors in bfs
  queue.offer(i * n + j);
  board[i][j] = '#';
 }
http://blog.welkinlan.com/2015/11/17/surrounded-regions-leetcode-java/
We can use Queue, remove and add
   public void solve(char[][] board) {
        int row = board.length;
        if (row == 0) return;
        int col = board[0].length;
        // store the index of '0'
        ArrayList<Integer> xIndex = new ArrayList<Integer>();
        ArrayList<Integer> yIndex = new ArrayList<Integer>();
        // scan 4 sides of the matrix, store all 'O's
        for (int i = 0; i < row; i++){
            // left border
            if (board[i][0] == 'O'){
                xIndex.add(i);
                yIndex.add(0);
            }
            // right border
            if (board[i][col - 1] == 'O'){
                xIndex.add(i);
                yIndex.add(col - 1);
            }
        }
        for (int i = 0; i < col; i++){
            // top border
            if (board[0][i] == 'O'){
                xIndex.add(0);
                yIndex.add(i);
            }
            // bottom border
            if (board[row - 1][i] == 'O'){
                xIndex.add(row - 1);
                yIndex.add(i);
            }
        }
        // iteratively (recursively) replace all 'O's connected to the 'O's on the sides as 'Y'
        int k = 0;
        while (k < xIndex.size()) {
            int x = xIndex.get(k);
            int y = yIndex.get(k);
            board[x][y] = 'Y'; // this '0' is connected to '0's on the border, so it won't be flipped
            // try 4 directions
            if (x > 0 && board[x - 1][y] == 'O') {
                xIndex.add(xIndex.size() - 1,x - 1);
                yIndex.add(yIndex.size() - 1,y);
            }
            if (x < row - 1 && board[x + 1][y] == 'O') {
                xIndex.add(xIndex.size() - 1,x + 1);
                yIndex.add(yIndex.size() - 1,y);
            }
            if (y > 0 && board[x][y - 1] == 'O') {
                xIndex.add(xIndex.size() - 1,x);
                yIndex.add(yIndex.size() - 1,y - 1);
            }
            if (y<col-1 && board[x][y + 1] == 'O') {
                xIndex.add(xIndex.size() - 1,x);
                yIndex.add(yIndex.size() - 1,y + 1);
            }
            k++;
        }
        //recover all 'Y's as 'O', flip other 'O's as 'X'
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (board[i][j] == 'O') board[i][j] = 'X';
                if (board[i][j] == 'Y') board[i][j] = 'O';
            }
        }
    }
http://rleetcode.blogspot.com/2014/01/surround-regions-java.html
A little different BFS: SPace: O(MN)
http://yucoding.blogspot.com/2013/08/leetcode-question-131-surrounded-regions.html
     void solve(vector<vector<char>> &board) {
        int row = board.size();  //get row number
        if (row==0){return;}
        int col = board[0].size(); // get column number
         
        vector<vector<bool> > bb(row, vector<bool>(col)); //result vector
        queue<pair<int,int> > q; // queue for BFS
                //search "O" from 1st row
        for (int i=0;i<col;i++){
            if (board[0][i]=='O'){
                q.push(make_pair(0,i));
                bb[0][i]=true;
            }
        }
        //search "O" from 1st column
        for (int i=0;i<row;i++){
            if (board[i][0]=='O'){
                q.push(make_pair(i,0));
                bb[i][0]=true;
            }
        }
        //search "O" from last row
        for (int i=0;i<col;i++){
            if (board[row-1][i]=='O'){
                q.push(make_pair(row-1,i));
                bb[row-1][i]=true;
            }
        }
        //search "O" from last column
        for (int i=0;i<row;i++){
            if (board[i][col-1]=='O'){
                q.push(make_pair(i,col-1));
                bb[i][col-1]=true;
            }
        }
        //BFS
        int i,j; // current position
        while (!q.empty()){
            //get current live "O"
            i = q.front().first;
            j = q.front().second;
             
            //pop up queue
            q.pop();
             
            //search four directions
            if (i-1>0 && board[i-1][j]=='O' && bb[i-1][j]==false){bb[i-1][j]=true; q.push(make_pair(i-1,j));} //top
            if (i+1<row-1 && board[i+1][j]=='O'&& bb[i+1][j]==false){bb[i+1][j]=true; q.push(make_pair(i+1,j));} // bottom
            if (j-1>0 && board[i][j-1]=='O'&& bb[i][j-1]==false){bb[i][j-1]=true; q.push(make_pair(i,j-1));} // left
            if (j+1<col-1 && board[i][j+1]=='O'&& bb[i][j+1]==false){bb[i][j+1]=true; q.push(make_pair(i,j+1));} // right
        }
         
        //Get result
        for (int i=0;i<row;i++){
            for (int j=0;j<col;j++){
                if (board[i][j]=='O'&&bb[i][j]==false){
                    board[i][j]='X';
                }
            }
        }
         
        return;
            
    }
http://www.cnblogs.com/huntfor/p/3898068.html
28         q.offer(i * code + j);//将二维下标压缩成一维,方便存储
30             int tem = q.poll();
31             int row = tem / code;
32             int col = tem % code;

http://fisherlei.blogspot.com/2013/03/leetcode-surrounded-regions-solution.html
首先得想法就是BFS。对于每一个O,扫描其相邻节点,然后标示之,如果一个联通区域中有任何一个O在边界上,则保留之,否则清除该联通域
https://en.wikipedia.org/wiki/Flood_fill
The flood-fill algorithm takes three parameters: a start node, a target color, and a replacement color. The algorithm looks for all nodes in the array that are connected to the start node by a path of the target color and changes them to the replacement color. 

Most practical implementations use a loop for the west and east directions as an optimization to avoid the overhead of stack or queue management: //TODO
Flood-fill (node, target-color, replacement-color):
 1. Set Q to the empty queue.
 2. If the color of node is not equal to target-color, return.
 3. Add node to Q.
 4. For each element N of Q:
 5.         Set w and e equal to N.
 6.         Move w to the west until the color of the node to the west of w no longer matches target-color.
 7.         Move e to the east until the color of the node to the east of e no longer matches target-color.
 8.         For each node n between w and e:
 9.             Set the color of n to replacement-color.
10.             If the color of the node to the north of n is target-color, add that node to Q.
11.             If the color of the node to the south of n is target-color, add that node to Q.
12. Continue looping until Q is exhausted.
13. Return.
https://leetcode.com/discuss/26522/share-my-clean-java-code

X. Union Find
https://aaronice.gitbooks.io/lintcode/union_find/surrounded_regions.html
一种比较巧妙的思路是从边缘的'O'出发,通过DFS,所有能够遍历的'O'都可以暂时被标记为'#',那么剩下未能被标记的'O'说明被surrounded,需要在遍历结束之后全部转为'X'。(用DFS或者BFS要警惕栈溢出)
另一种方法是用Union Find,将与边缘相连通的'O'全部union到一个dummy node(也可以用hasEdge[]来存储,不过内存占用更多), 最终将没有和这个dummy node是一个component的'O'点全部标记为'X'。



+
https://segmentfault.com/a/1190000007010346
    int row, col;
    public void solve(char[][] board) {
        if (board == null || board.length == 0) return;
        row = board.length;
        col = board[0].length;
        UnionFind uf = new UnionFind(row*col+1);
        int dummy = row*col;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (board[i][j] == 'O') {
                    if (i == 0 || i == row-1 || j == 0 || j == col-1) uf.union(node(i, j), dummy);
                    else {
                        if (i > 0 && board[i-1][j] == 'O') uf.union(node(i, j), node(i-1, j));
                        if (i > 0 && board[i+1][j] == 'O') uf.union(node(i, j), node(i+1, j));
                        if (j > 0 && board[i][j-1] == 'O') uf.union(node(i, j), node(i, j-1));
                        if (j > 0 && board[i][j+1] == 'O') uf.union(node(i, j), node(i, j+1));
                    }
                }
            }
        }
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (uf.isConnected(node(i, j), dummy)) board[i][j] = 'O';
                else board[i][j] = 'X';
            }
        }
    }
    public int node(int i, int j) {
        return i*col+j;
    }
}

class UnionFind {
    int[] parents;
    public UnionFind(int n) {
        parents = new int[n];
        for (int i = 0; i < n; i++) parents[i] = i;
    }
    public void union(int n1, int n2) {
        int r1 = find(n1);
        int r2 = find(n2);
        if (r1 != r2) parents[r1] = r2;
    }
    public int find(int node) {
        if (parents[node] == node) return node;
        parents[node] = find(parents[node]);
        return parents[node];
    }    
    public boolean isConnected(int n1, int n2) {
        return find(n1) == find(n2);
    }
}
http://likesky3.iteye.com/blog/2240270
思路1:和Number of Islands类似,但是此题用DFS会栈溢出,因此使用BFS。从四个边缘的元素开始BFS, 遇到 O 改成特殊字符M,最后没有被修改的O就是被X包围的,应当改为X, 并且把M恢复成O即可。 BFS搜索时队列中维护的是所有未展开BFS的 O,队列记录这些 O的位置。 
思路2:利用union find算法,将所有边界可达的O union在一起。设置一个根节点oRoot,边界上的所有O同其union上,非边界的O同其上下左右的O进行union。扫描完board后,那些最终没有和oRoot union在一起的O是需要翻转的。实现时特别注意要将oRoot的秩设得足够大,比如设为矩阵元素个数,确保每个oRoot始终是边界可达O集合的根元素。因为在大矩阵情况下,中间可能产生比较大的秩,若oRoot秩比较小,根元素会被替换从而出错。 
对比Number of Islands, 这里使用一维数组实现union find内部数据结构更简洁。

  1.     public void solve(char[][] board) {  
  2.         if (board == null || board.length == 0 || board[0].length == 0)  
  3.             return;  
  4.         int rows = board.length, cols = board[0].length;  
  5.         int oRoot = rows * cols;  
  6.         initUnionFind(rows * cols);  
  7.         for (int i = 0; i < rows; i++) {  
  8.             for (int j = 0; j < cols; j++) {  
  9.                 if (board[i][j] == 'X'continue;  
  10.                 int curr = i * cols + j;  
  11.                 if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1) {  
  12.                     union(curr, oRoot);  
  13.                 } else {  
  14.                     if (j + 1 < cols && board[i][j + 1] == 'O')  
  15.                         union(curr, i * cols + j + 1);  
  16.                     if (j - 1 >= 0 && board[i][j - 1] == 'O')  
  17.                         union(curr, i * cols + j - 1);  
  18.                     if (i + 1 < rows && board[i + 1][j] == 'O')  
  19.                         union(curr, (i + 1) * cols + j);  
  20.                     if (i - 1 >= 0 && board[i - 1][j] == 'O')  
  21.                         union(curr, (i - 1) * cols + j);  
  22.                 }  
  23.             }  
  24.         }  
  25.         for (int i = 0; i < rows; i++) {  
  26.             for (int j = 0; j < cols; j++) {  
  27.                 if (board[i][j] == 'O' && find(i * cols + j) != oRoot) {  
  28.                     board[i][j] = 'X';  
  29.                 }  
  30.             }  
  31.         }  
  32.     }  
  33.     int[] s;  
  34.     int[] rank;  
  35.     private void initUnionFind(int n) {  
  36.         s = new int[n + 1];  
  37.         rank = new int[n + 1];  
  38.         for (int i = 0; i <= n; i++)  
  39.             s[i] = i;  
  40.         rank[n] = n + 1;  //??
  41.     }  
  42.     private int find(int p) {  
  43.         if (s[p] == p) return p;  
  44.         else return s[p] = find(s[p]);  
  45.     }  
  46.     private void union(int p, int q) {  
  47.         int pRoot = find(p), qRoot = find(q);  
  48.         if (pRoot == qRoot) return;  
  49.         if (rank[pRoot] < rank[qRoot]) {  
  50.             s[pRoot] = qRoot;  
  51.         } else {  
  52.             if (rank[pRoot] == rank[qRoot])  
  53.                 rank[pRoot]++;  
  54.             s[qRoot] = pRoot;  
  55.         }  
  56.     }  

https://leetcode.com/problems/surrounded-regions/discuss/41617/Solve-it-using-Union-Find

Hi. So here is my accepted code using Union Find data structure. The idea comes from the observation that if a region is NOT captured, it is connected to the boundry. So if we connect all the 'O' nodes on the boundry to a dummy node, and then connect each 'O' node to its neighbour 'O' nodes, then we can tell directly whether a 'O' node is captured by checking whether it is connected to the dummy node.

    int[] unionSet; // union find set
    boolean[] hasEdgeO; // whether an union has an 'O' which is on the edge of the matrix
    
    public void solve(char[][] board) {
        if(board.length == 0 || board[0].length == 0) return;
        
        // init, every char itself is an union
        int height = board.length, width = board[0].length;
        unionSet = new int[height * width];
        hasEdgeO = new boolean[unionSet.length];
        for(int i = 0;i<unionSet.length; i++) unionSet[i] = i;
        for(int i = 0;i<hasEdgeO.length; i++){
            int x = i / width, y = i % width;
            hasEdgeO[i] = (board[x][y] == 'O' && (x==0 || x==height-1 || y==0 || y==width-1));
        }
        
        // iterate the matrix, for each char, union it + its upper char + its right char if they equals to each other
        for(int i = 0;i<unionSet.length; i++){
            int x = i / width, y = i % width, up = x - 1, right = y + 1;
            if(up >= 0 && board[x][y] == board[up][y]) union(i,i-width);
            if(right < width && board[x][y] == board[x][right]) union(i,i+1);
        }
        
        // for each char in the matrix, if it is an 'O' and its union doesn't has an 'edge O', the whole union should be setted as 'X'
        for(int i = 0;i<unionSet.length; i++){
            int x = i / width, y = i % width;
            if(board[x][y] == 'O' && !hasEdgeO[findSet(i)]) 
                board[x][y] = 'X'; 
        }
    }
    
    private void union(int x,int y){
        int rootX = findSet(x);
        int rootY = findSet(y);
        // if there is an union has an 'edge O',the union after merge should be marked too
        boolean hasEdgeO = this.hasEdgeO[rootX] || this.hasEdgeO[rootY];
        unionSet[rootX] = rootY;
        this.hasEdgeO[rootY] = hasEdgeO;
    }
    
    private int findSet(int x){
        if(unionSet[x] == x) return x;
        unionSet[x] = findSet(unionSet[x]);
        return unionSet[x];
    }
Read full article from LeetCode – Surrounded Regions (Java)

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts