Leetcode 200: Find the number of islands


Find the number of islands | GeeksforGeeks
Given a boolean 2D matrix, find the number of islands.
This is an variation of the standard problem: “Counting number of connected components in a undirected graph”.
Time complexity: O(ROW x COL)
connected component of an undirected graph is a subgraph in which every two vertices are connected to each other by a path(s), and which is connected to no other vertices outside the subgraph.
The problem can be easily solved by applying DFS() on each component. In each DFS() call, a component or a sub-graph is visited. We will call DFS on the next un-visited component. The number of calls to DFS() gives the number of connected components.
                        {1, 1, 0, 0, 0},
                        {0, 1, 0, 0, 1},
                        {1, 0, 0, 1, 1},
                        {0, 0, 0, 0, 0},
                        {1, 0, 1, 0, 1}
X. DFS
http://blog.csdn.net/xudli/article/details/45912547
void DFS(int M[][COL], int row, int col, bool visited[][COL])
{
    // These arrays are used to get row and column numbers of 8 neighbors
    // of a given cell
    static int rowNbr[] = {-1, -1, -1,  0, 0,  1, 1, 1};
    static int colNbr[] = {-1,  0,  1, -1, 1, -1, 0, 1};
    // Mark this cell as visited
    visited[row][col] = true;
    // Recur for all connected neighbours
    for (int k = 0; k < 8; ++k)
        if (isSafe(M, row + rowNbr[k], col + colNbr[k], visited) )
            DFS(M, row + rowNbr[k], col + colNbr[k], visited);
}
// The main function that returns count of islands in a given boolean
// 2D matrix
int countIslands(int M[][COL])
{
    // Make a bool array to mark visited cells.
    // Initially all cells are unvisited
    bool visited[ROW][COL];
    memset(visited, 0, sizeof(visited));
    // Initialize count as 0 and travese through the all cells of
    // given matrix
    int count = 0;
    for (int i = 0; i < ROW; ++i)
        for (int j = 0; j < COL; ++j)
            if (M[i][j] && !visited[i][j]) // If a cell with value 1 is not
            {                              // visited yet, then new island found
                DFS(M, i, j, visited);     // Visit all cells in this island.
                ++count;                   // and increment island count
            }
    return count;
}
只需要对每一个陆地区域做一次dfs,每次dfs中将已经遍历的陆地网格“1”变为水域网格“2”(防止再次遍历导致重复)。对每次dfs计数,总共dfs的次数即为岛屿总数。应注意,grid为空的特殊情况应该排除
http://www.programcreek.com/2014/04/leetcode-number-of-islands-java/
http://blog.csdn.net/ljiabin/article/details/44975717
https://discuss.leetcode.com/topic/13248/very-concise-java-ac-solution
Don't use extra visited space:
If we need restore grid, we just need map 2 to 1.
public int numIslands(char[][] grid) {
    if (grid==null || grid.length==0 || grid[0].length==0) return 0;
    int count = 0;
 
    for (int i=0; i<grid.length; i++) {
        for (int j=0; j<grid[0].length; j++) {
            if(grid[i][j] == '1'){
                count++;
                merge(grid, i, j);
            }
        }
    }
    return count;
}
 public void merge(char[][] grid, int i, int j){
    //validity checking
    if(i<0 || j<0 || i>grid.length-1 || j>grid[0].length-1)
        return;
 
    //if current cell is water or visited
    if(grid[i][j] != '1') return;
 
    //set visited cell to '2'
    grid[i][j] = '2';
 
    //merge all adjacent land
    merge(grid, i-1, j);
    merge(grid, i+1, j);
    merge(grid, i, j-1);
    merge(grid, i, j+1);
}
http://www.fgdsb.com/2015/02/09/number-of-islands/
X. BFS:
http://blog.hyoung.me/cn/2017/03/breadth-first-search/
这道题虽然简单,但包含了两个使用 BFS 时的关键技巧。第一,对于图(Graph)或矩阵(Board)而言,在使用 BFS 时往往就需要记录访问信息以避免重复访问。第二,对于矩阵而言,使用偏移变量(line 30~31)来表示搜索的方向往往会使得逻辑表达更加清楚,实现起来也更加简洁。
如前面所说,我们也同样可以使用 DFS 来解决。但栈中递归函数最多可能积累 O(NM)次,即整个矩阵的大小,当 N 或 M 较大时,就有可能会爆栈。
http://www.cnblogs.com/tonyluis/p/4558750.html
-- Change origin data: 1 to 0.
public int numIslands(char[][] grid) {
    int res = 0;
    for (int i = 0; i < grid.length; i++)
        for (int j = 0; j < grid[0].length; j++)
            if (grid[i][j] == '1') {
                grid[i][j] = '0';
                bfs(grid, i * grid[0].length + j);
                res++;
            }
    return res;
}
public static void bfs(char[][] grid, int num) {
    Queue<Integer> queue = new LinkedList<Integer>();
    queue.add(num);
    while (!queue.isEmpty()) {
        num = queue.poll();
        int row = num / grid[0].length;
        int col = num - row * grid[0].length;
        if (row - 1 >= 0 && grid[row - 1][col] == '1') {
            grid[row - 1][col] = '0';
            queue.add(num - grid[0].length);
        }
        if (row + 1 <= grid.length - 1 && grid[row + 1][col] == '1') {
            grid[row + 1][col] = '0';
            queue.add(num + grid[0].length);
        }
        if (col - 1 >= 0 && grid[row][col - 1] == '1') {
            grid[row][col - 1] = '0';
            queue.add(num - 1);
        }
        if (col + 1 <= grid[0].length - 1 && grid[row][col + 1] == '1') {
            grid[row][col + 1] = '0';
            queue.add(num + 1);
        }
    }
}

http://blog.csdn.net/derrantcm/article/details/47970795
Don't change origin data. - Use extra visited array.
public int numIslands(char[][] grid) { // 参数校验 if (grid == null || grid.length == 0 || grid[0].length == 0) { return 0; } // 元素默认值是false boolean[][] visited = new boolean[grid.length][grid[0].length]; int result = 0; for (int i = 0; i < grid.length; i++) { for (int j = 0; j < grid[0].length; j++) { // 如果此位置没有被访问过,并且此位置是岛,就里德广度优先遍历 if (!visited[i][j] && grid[i][j] == '1') { result++; bfs(grid, visited, i, j); } } } return result; } private void bfs(char[][] grid, boolean[][] visited, int row, int col) { if (row >= 0 && row < grid.length // 行合法 && col >= 0 && col < grid[0].length // 列合法 && !visited[row][col] // 没有访问过 && grid[row][col] == '1') { // 是岛上陆地 // 标记此位置已经访问过了 visited[row][col] = true; // 上 bfs(grid, visited, row - 1, col); // 右 bfs(grid, visited, row, col + 1); // 下 bfs(grid, visited, row + 1, col); // 左 bfs(grid, visited, row, col - 1); } }
http://www.ideserve.co.in/learn/number-of-clusters-of-1s


X. Union Find
http://likesky3.iteye.com/blog/2240170
这里阐述下union-find思路,思路很直接,我们需要把相连在一起的1union起来,最后数下union了多少个集合1。输入时一个m*n矩阵,union-find相应地需要一个二维数组保存信息,采用按秩求并方法,初始时每个1元素的秩为-1,0元素不参与union,记为0。扫描数组,对于(i,j)元素,查看其是否需要同右边和下边相邻元素合并,其上边和左边不需要,因为按这种扫描顺序已经查看过。一个相邻的1集合合并完,只有根节点的秩为负数,而其余节点均指向相应根节点的下标为正数,因此扫描完整个集合,通过检查秩数组中负数的个数即可知道grid中的岛屿数。特别注意,在union时若两个元素根相同说明已经被union过,不能再执行union逻辑否则会导致该集合的根消失而Wrong Answer。 

--第二版union find,一维数组存储,更清晰,使用count计数岛屿数,初始时每个1所在位置为一个岛屿,伴随union过程,相连的1代表的岛屿进行合并,每一次成功合并,岛屿数减一。实现如Method 4所示。当然此题用BFS或者DFS代码比较简洁, DFS的隐患是可能堆栈溢出。 
  1. public int numIslands1(char[][] grid) {  
  2.         if (grid == null || grid.length == 0 || grid[0].length == 0)  
  3.             return 0;  
  4.         initUnionFind(grid);  
  5.         int rows = grid.length;  
  6.         int cols = grid[0].length;  
  7.         for (int i = 0; i < rows; i++) {  
  8.             for (int j = 0; j < cols; j++) {  
  9.                 if (grid[i][j] == '1') {  
  10.                     for (int k = 0; k < 4; k++) {  
  11.                         int iNeigh = i + deltaY[k];  
  12.                         int jNeigh = j + deltaX[k];  
  13.                         if (iNeigh >= 0 && iNeigh < rows && jNeigh >= 0 && jNeigh < cols && grid[iNeigh][jNeigh] == '1') {  
  14.                             union(i * cols + j, iNeigh * cols + jNeigh);  
  15.                         }  
  16.                     }  
  17.                 }  
  18.             }  
  19.         }  
  20.         return count;  
  21.     }  
  22.     int[] s;  
  23.     int[] rank;  
  24.     int count = 0;  
  25.     int[] deltaX = {001, -1};  
  26.     int[] deltaY = {1, -100};  
  27.     private void union(int p, int q) {  
  28.         int pRoot = find(p), qRoot = find(q);  
  29.         if (pRoot == qRoot) return;  
  30.         if (s[pRoot] > s[qRoot]) {  
  31.             s[pRoot] = qRoot;  
  32.         } else {  
  33.             if (s[pRoot] == s[qRoot])  
  34.                 s[pRoot]--;  
  35.             s[qRoot] = pRoot;  
  36.         }  
  37.         count--;  
  38.     }  
  39.     private int find1(int p) {  
  40.         if (s[p] == p)  
  41.             return p;  
  42.         else  
  43.             return s[p] = find(s[p]);  
  44.     }  
  45.     private void union1(int p, int q) {  
  46.         int pRoot = find(p), qRoot = find(q);  
  47.         if (pRoot == qRoot) return;  
  48.         if (rank[pRoot] < rank[qRoot]) {  
  49.             s[pRoot] = qRoot;  
  50.         } else {  
  51.             if (rank[pRoot] == rank[qRoot])  
  52.                 rank[pRoot]++;  
  53.             s[qRoot] = s[pRoot];  
  54.         }  
  55.         count--;  
  56.     }  
https://discuss.leetcode.com/topic/33947/java-union-find-solution
You only need to do it for two directions, which are "right" and "down", because all "left" and "up" has already been seen if exists connection (undirected for Union Find).
   int[][] distance = {{1,0},{-1,0},{0,1},{0,-1}};
    public int numIslands(char[][] grid) {  
        if (grid == null || grid.length == 0 || grid[0].length == 0)  {
            return 0;  
        }
        UnionFind uf = new UnionFind(grid);  
        int rows = grid.length;  
        int cols = grid[0].length;  
        for (int i = 0; i < rows; i++) {  
            for (int j = 0; j < cols; j++) {  
                if (grid[i][j] == '1') {  
                    for (int[] d : distance) {
                        int x = i + d[0];
                        int y = j + d[1];
                        if (x >= 0 && x < rows && y >= 0 && y < cols && grid[x][y] == '1') {  
                            int id1 = i*cols+j;
                            int id2 = x*cols+y;
                            uf.union(id1, id2);  
                        }  
                    }  
                }  
            }  
        }  
        return uf.count;  
    }
Union Find:
    class UnionFind {
        int[] father;  
        int m, n;
        int count = 0;
        UnionFind(char[][] grid) {  
            m = grid.length;  
            n = grid[0].length;  
            father = new int[m*n];  
            for (int i = 0; i < m; i++) {  
                for (int j = 0; j < n; j++) {  
                    if (grid[i][j] == '1') {
                        int id = i * n + j;
                        father[id] = id;
                        count++;
                    }
                }  
            }  
        }
        public void union(int node1, int node2) {  
            int find1 = find(node1);
            int find2 = find(node2);
            if(find1 != find2) {
                father[find1] = find2;
                count--;
            }
        }
        public int find (int node) {  
            if (father[node] == node) {  
                return node;
            }
            father[node] = find(father[node]);  
            return father[node];
        }
    }
https://leetcode.com/discuss/31768/ac-java-solution-using-union-find-with-explanations
Basic idea is to iterate through every node's neighbours and marked them if they aren't connected. Finally, if it was the root node then increase the total number of islands.
private int[] sz; private int[] id; private int N, M; public int find(int p) { while (id[p] != p) p = id[p]; return p; } public void union(int p, int q) { int rootP = find(p); int rootQ = find(q); if (rootP == rootQ) return; if (sz[rootP] < sz[rootQ]) {sz[rootQ] += sz[rootP]; id[rootP] = id[rootQ];} else {sz[rootP] += sz[rootQ]; id[rootQ] = id[rootP];} } private boolean inside(int x, int y) { return (x >= 0 && y >= 0 && x < N && y < M); } public int numIslands(char[][] grid) { if (grid == null || grid.length ==0) return 0; N = grid.length; M = grid[0].length; sz = new int[N*M]; id = new int[N*M]; for (int i = 0; i < N*M; i++) { id[i] = i; sz[i] = 1; } for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) if (grid[i][j] != '0') { int tmp = i*M + j; if (inside(i-1, j) && grid[i-1][j] != '0') union(tmp, tmp - M); if (inside(i, j-1) && grid[i][j-1] != '0') union(tmp, tmp - 1); if (inside(i+1, j) && grid[i+1][j] != '0') union(tmp, tmp + M); if (inside(i, j+1) && grid[i][j+1] != '0') union(tmp, tmp + 1); } } int islands = 0, i = 0; while (i < N*M) { if (i == id[i] && grid[i/M][i%M] != '0') islands++; i++; } return islands; }
http://www.tangjikai.com/algorithms/leetcode-200-number-of-islands
  1. class UnionFind(object):
  2. def __init__(self, m, n):
  3. self.father = dict()
  4. self.count = m * n
  5. for x in range(m):
  6. for y in range(n):
  7. Id = x * n + y
  8. self.father[Id] = Id
  9. def compressed_find(self, x):
  10. parent = self.father.get(x)
  11. while parent != self.father.get(parent):
  12. parent = self.father.get(parent)
  13. temp = -1
  14. fa = self.father.get(x)
  15. while fa != self.father.get(fa):
  16. temp = self.father.get(fa)
  17. self.father[fa] = parent
  18. fa = temp
  19. return parent
  20. def union(self, x, y):
  21. fa_x = self.compressed_find(x)
  22. fa_y = self.compressed_find(y)
  23. if fa_x != fa_y:
  24. self.father[fa_x] = fa_y
  25. self.count -=1
  26. class Solution(object):
  27. def convertToId(self, x, y, n):
  28. return x * n + y
  29. def numIslands(self, grid):
  30. """
  31. :type grid: List[List[str]]
  32. :rtype: int
  33. """
  34. if grid == None or len(grid) == 0:
  35. return 0
  36. m = len(grid)
  37. n = len(grid[0])
  38. uf = UnionFind(m, n)
  39. for i in range(m):
  40. for j in range(n):
  41. if grid[i][j] == '1':
  42. if i < m - 1 and grid[i+1][j] == '1':
  43. uf.union(self.convertToId(i, j, n), self.convertToId(i+1, j, n))
  44. if j < n - 1 and grid[i][j+1] == '1':
  45. uf.union(self.convertToId(i, j, n), self.convertToId(i, j+1, n))
  46. else:
  47. uf.count -= 1
  48. return uf.count
https://gist.github.com/pdu/6e950a13964701507252
private int[] sz;
private int[] id;
private int N, M;

public int find(int p) {
    while (id[p] != p)
        p = id[p];
    return p;
}

public void union(int p, int q) {
    int rootP = find(p);
    int rootQ = find(q);
    if (rootP == rootQ) return;

    if (sz[rootP] < sz[rootQ])  {sz[rootQ] += sz[rootP]; id[rootP] = id[rootQ];}
    else                        {sz[rootP] += sz[rootQ]; id[rootQ] = id[rootP];}
}

private boolean inside(int x, int y) {
    return (x >= 0 && y >= 0 && x < N && y < M);
}

public int numIslands(char[][] grid) {
    if (grid == null || grid.length ==0) return 0;
    N = grid.length;
    M = grid[0].length;
    sz = new int[N*M];
    id = new int[N*M];
    for (int i = 0; i < N*M; i++) {
        id[i] = i;
        sz[i] = 1;
    }
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < M; j++)
            if (grid[i][j] != '0') {
                int tmp = i*M + j;
                if (inside(i-1, j) && grid[i-1][j] != '0') union(tmp, tmp - M);
                if (inside(i, j-1) && grid[i][j-1] != '0') union(tmp, tmp - 1);
                if (inside(i+1, j) && grid[i+1][j] != '0') union(tmp, tmp + M);
                if (inside(i, j+1) && grid[i][j+1] != '0') union(tmp, tmp + 1);
            }
    }
    int islands = 0, i = 0;
    while (i < N*M) {
        if (i == id[i] && grid[i/M][i%M] != '0') islands++;
        i++;
    }
    return islands;
}

http://betterpoetrythancode.blogspot.com/2015/01/number-of-countries.html
https://leetcode.com/discuss/31768/ac-java-solution-using-union-find-with-explanations
      public class Block{
           int x;
           int y;
           public Block(int x,int y)
           {
                this.x=x;
                this.y=y;
           }
      }
      public int solution(int[][] board)
      {
           int TAG=Integer.MIN_VALUE;
           int counter=0;
           for(int i=0;i<board.length;i++)
           {
                for(int j=0;j<board[0].length;j++)
                {
                     if(board[i][j]!=TAG)
                     {
                          bfs(board,i,j);
                          counter+=1;
                     }
                }
           }
           return counter;
      }
      public void bfs(int[][] board,int startX,int startY)
      {
           int TAG1=Integer.MIN_VALUE;
           int TAG2=board[startX][startY];
           int m=board.length;
           int n=board[0].length;
           Queue<Block> queue=new LinkedList<Block>();
           queue.offer(new Block(startX,startY));
           while(queue.isEmpty()==false)
           {
                int queueSize=queue.size();
                for(int i=0;i<queue.size();i++)
                {
                     Block cur=queue.poll();
                     board[cur.x][cur.y]=TAG1;
                     if(cur.x+1<m&&board[cur.x+1][cur.y]==TAG2)
                          queue.offer(new Block(cur.x+1,cur.y));
                     if(cur.y+1<n&&board[cur.x][cur.y+1]==TAG2)
                          queue.offer(new Block(cur.x,cur.y+1));
                     if(cur.x-1>=0&&board[cur.x-1][cur.y]==TAG2)
                          queue.offer(new Block(cur.x-1,cur.y));
                     if(cur.y-1>=0&&board[cur.x][cur.y-1]==TAG2)
                          queue.offer(new Block(cur.x,cur.y-1));
                }
           }
      }
Pond Sizes
You have an integer matrix representing a plot of land, where the value at that location
represents the height above sea level. A value of zero indicates water. A pond is a region of water
connected vertically, horizontally, or diagonally. The size of the pond is the total number of

connected water cells. Write a method to compute the sizes of all ponds in the matrix

Arraylist<Integer> computePondSizes(int[][] land) {
        Arraylist<Integer> pondSizes = new Arraylist<Integer>();
        for (int r = 0; r < land.length; r++) {
                for (int c = 0; c < land[r].length; c++) {
                        if (land[r][c] == 0) {//Optional. Would return anyway.
                                int size = computeSize(land, r, c);
                                pondSizes.add(size);
                        }
                }
        }
        return pondSizes;
}

int computeSize(int[][] land, int row, int col) {
  /* If out of bounds or already visited. */
  if (row < 0 || col< 0 || row >= land.length || col >= land[row].length || land[row][col) != 0) {
     //visited or not water
    return 0;
  }
  int size = 1;
  land[row][col] = -1; // Mark visited
  for (int dr = -1; dr <= 1; dr++) {
    for (int de = -1; de <= 1; de++) {
        size += computeSize(land, row + ctr, col + de);
      }
  }
  return size;
}

You might also notice that the for loop iterates through nine cells, not eight. It includes the current cell.

We could add a line in there to not recurse if dr == 0 and de == 0. This really doesn't save us much.
We'll execute this if-statement in eight cells unnecessarily, just to avoid one recursive call. The recursive call returns immediately since the cell is marked as visited.

If you don't like modifying the input matrix, you can create a secondary visited matrix.
Arraylist<Integer> computePondSizes(int[][] land) {
        boolean[][] visited = new boolean[land.length][land[0].length];
        Arraylist<Integer> pondSizes = new Arraylist<Integer>();
        for (int r = 0; r < land.length; r++) {
                for (int c = 0; c < land[r].length; c++) {
                        int size = computeSize(land, visited, r, c);
                        if (size > 0) {
                                pondSizes.add(size);
                        }
                }
        }
        return pondSizes;
}

int computeSize(int[][] land, boolean[][] visited, int row, int col) {
        /* If out of bounds or already visited. */
        if (row < 0 || col < 0 || row >= land.length || col >= land[row].length ||
            visited[row][col] || land[row][col] != 0) {
                return 0;
        }
        int size = 1;
        visited[row][col] = true;
        for (int dr = -1; dr <= 1; dr++) {
                for (int de = -1; de <= 1; de++) {
                        size += computeSize(land, visited, row + dr, col + de);
                }
        }
        return size;
}
https://segmentfault.com/a/1190000003753307
Q:如何找湖的数量呢?湖的定义是某个0,其上下左右都是同一个岛屿的陆地。A:我们可以先用Number of island的方法,把每个岛标记成不同的ID,然后过一遍整个地图的每个点,如果是0的话,就DFS看这块连通水域是否被同一块岛屿包围,如果出现了不同数字的陆地,则不是湖。
    public int numberOfLakes(int[][] world){
        int islandId = 2;
        for(int i = 0; i < world.length; i++){
            for(int j = 0; j < world[0].length; j++){
                if(world[i][j] == 1){
                    findIsland(world, i, j, islandId);
                    islandId++;
                }
            }
        }
        int lake = 0;
        for(int i = 0; i < world.length; i++){
            for(int j = 0; j < world[0].length; j++){
                if(world[i][j] == 0){
                    // 找到当前水域的邻接陆地编号
                    int currId = 0;
                    if(i > 0) currId = (world[i - 1][j] != 0 ? world[i - 1][j] : currId);
                    if(j > 0) currId = (world[i][j - 1] != 0 ? world[i][j - 1] : currId);
                    if(i < world.length - 1) currId = (world[i + 1][j] != 0 ? world[i + 1][j] : currId);
                    if(j < world[0].length - 1) currId = (world[i][j + 1] != 0 ? world[i][j + 1] : currId);
                    // 如果该点是湖,加1
                    if(findLake(world, i, j, currId)){
                        lake++;
                    }
                }
            }
        }
        return lake;
    }
http://www.1point3acres.com/bbs/thread-175393-1-1.html
numberIsland找不同形状的Island的个数
比如
1010
0100
0000. 鍥磋鎴戜滑@1point 3 acres
1010
0100


这样上下两个岛形状一样,return 
dfs遍历的方向可以优化一下,只需要右边,右下,下,左下四个方向即可。
关于这题的做法,我们先BFS把所有的岛存下来,然后发现第一个岛的index是(0,0) -> (1,1) ->(0,2),convert成一维坐标i*m + j是0 -> 6 -> 2,sort好了是0 -> 2 -> 6。 同样的方法做第一个岛(4,0) -> (5,1) -> (4,2), convert成一维坐标16->22->18, 然后sort一下,大家减去第一个数字又变成0->2->6 就能判断两个岛是一样了
刚刚想了下 发现二维转化成一维还是有点问题的,还是直接用二维的方法比吧

举个bug的例子?
[0][1][1]
[1][0][0]

[1][1][1]
对 所以需要加一个判断 要求每层的node个数一样 但这样还不如二维比算了

请问两个岛如果经过旋转或翻转之后一样应该算一个还是两个啊?
算不同的
你是指这个吗?
[0][1][1]
[1][0][0]

[1][1][1]
这个没有问题呢,因为是转化成了一维唯一的数,所以每一个case都可以区分
- the way to transferToKey will not work 


  1.         public static int getIslandNumberWithDifferentShapes(int[][] matrix) {. 鍥磋鎴戜滑@1point 3 acres
  2.                 if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
  3.                         return 0;
  4.                 }
  5.                 . 1point 3acres 璁哄潧
  6.                 boolean[][] visited = new boolean[matrix.length][matrix[0].length];
  7.                 Set<String> set = new HashSet<String>();
  8.                 for (int i = 0; i < matrix.length; i++) {
  9.                         for (int j = 0; j < matrix[0].length; j++) {
  10.                                 if (!visited[i][j] && matrix[i][j] == 1) {
  11.                                         List<Integer> path = new ArrayList<Integer>();
  12.                                         helper(matrix, visited, i, j, path);
  13.                                         String str = transferToKey(path);.鏈枃鍘熷垱鑷�1point3acres璁哄潧
  14.                                         set.add(str);
  15.                                 }
  16.                         }
  17.                 }
  18.                 
  19.                 return set.size();
  20.         }. Waral 鍗氬鏈夋洿澶氭枃绔�,

  21.         private static String transferToKey(List<Integer> path) {
  22.                 StringBuilder sb = new StringBuilder();. from: 1point3acres.com/bbs 
  23.                 int diff = path.get(0) - 0;-google 1point3acres
  24.                 for (int i : path) {. visit 1point3acres.com for more.
  25.                         sb.append((i - diff) + "#");
  26.                 }.鐣欏璁哄潧-涓€浜�-涓夊垎鍦�
  27.                 return sb.toString();
  28.         }

  29.         private static void helper(int[][] matrix, boolean[][] visited, int x,
  30.                         int y, List<Integer> path) {
  31.                 if (x < 0 || x >= matrix.length || y < 0 || y >= matrix[0].length || visited[x][y] || matrix[x][y] != 1) {
  32.                         return;
  33.                 }. 1point 3acres 璁哄潧
  34.                 int n = matrix[0].length;
  35.                 int[] dx = {1, -1, 0, 0, 1, 1, -1, -1};. 鐣欏鐢宠璁哄潧-涓€浜╀笁鍒嗗湴
  36.                 int[] dy = {0, 0, 1, -1, 1, -1, 1, -1};. From 1point 3acres bbs
  37.                 visited[x][y] = true;
  38.                 path.add((x * n + y));
  39.                 for (int i = 0; i < dx.length; i++) {
  40.                         int nx = dx[i] + x;
  41.                         int ny = dy[i] + y;
  42.                         helper(matrix, visited, nx, ny, path);
  43.                 }
  44.         }
http://www.geeksforgeeks.org/find-number-of-islands/
http://www.geeksforgeeks.org/find-length-largest-region-boolean-matrix/
Consider a matrix with rows and columns, where each cell contains either a ‘0’ or a ‘1’ and any cell containing a 1 is called a filled cell. Two cells are said to be connected if they are adjacent to each other horizontally, vertically, or diagonally .If one or more filled cells are also connected, they form a region. find the length of the largest region.
Examples:
Input : M[][5] = { 0 0 1 1 0
                   1 0 1 1 0
                   0 1 0 0 0
                   0 0 0 0 1 }
Output : 6 
Ex: in the following example, there are 2 regions one with length 1 and the other as 6.
    so largest region : 6
A cell in 2D matrix can be connected to at most 8 neighbors. So in DFS, we make recursive calls for 8 neighbors. We keep track of the visited 1’s in every DFS and update maximum length region.
int isSafe(int M[][COL], int row, int col,
           bool visited[][COL])
{
    // row number is in range, column number is in
    // range and value is 1 and not yet visited
    return (row >= 0) && (row < ROW) &&
           (col >= 0) && (col < COL) &&
           (M[row][col] && !visited[row][col]);
}
// A utility function to do DFS for a 2D boolean
// matrix. It only considers the 8 neighbours as
// adjacent vertices
void DFS(int M[][COL], int row, int col,
         bool visited[][COL], int &count)
{
    // These arrays are used to get row and column
    // numbers of 8 neighbours of a given cell
    static int rowNbr[] = {-1, -1, -1, 0, 0, 1, 1, 1};
    static int colNbr[] = {-1, 0, 1, -1, 1, -1, 0, 1};
    // Mark this cell as visited
    visited[row][col] = true;
    // Recur for all connected neighbours
    for (int k = 0; k < 8; ++k)
    {
        if (isSafe(M, row + rowNbr[k], col + colNbr[k],
                                              visited))
        {
            // increment region length by one
            count++;
            DFS(M, row + rowNbr[k], col + colNbr[k],
                                    visited, count);
        }
    }
}
// The main function that returns largest  length region
// of a given boolean 2D matrix
int  largest(int M[][COL])
{
    // Make a bool array to mark visited cells.
    // Initially all cells are unvisited
    bool visited[ROW][COL];
    memset(visited, 0, sizeof(visited));
    // Initialize result as 0 and travesle through the
    // all cells of given matrix
    int result  = INT_MIN;
    for (int i = 0; i < ROW; ++i)
    {
        for (int j = 0; j < COL; ++j)
        {
            // If a cell with value 1 is not
            if (M[i][j] && !visited[i][j])
            {
                // visited yet, then new region found
                int count = 1 ;
                DFS(M, i, j, visited , count);
                // maximum region
                result = max(result , count);
            }
         }
    }
    return result ;
}

http://www.cnblogs.com/EdwardLiu/p/6288850.html
Find largest island in a board
 4     public int findLargestIsland(int[][] board) {
 5         if (board==null || board.length==0 || board[0].length==0) return 0;
 6         int m = board.length;
 7         int n = board[0].length;
 8         int maxArea = 0;
 9         for (int i=0; i<m; i++) {
10             for (int j=0; j<n; j++) {
11                 if (board[i][j] != 1) continue;
12                 int area = 0;
13                 area = dfs(board, i, j, m, n);
14                 maxArea = Math.max(maxArea, area);
15             }
16         }
17         return maxArea;
18     }
19     
20     
21     public int dfs(int[][] board, int i, int j, int m, int n) {
22         if (i<0 || i>=m || j<0 || j>=n || board[i][j]!=1) return 0;
23         int area = 1;
24         board[i][j] = 2;
25         area += dfs(board, i-1, j, m, n);
26         area += dfs(board, i+1, j, m, n);
27         area += dfs(board, i, j-1, m, n);
28         area += dfs(board, i, j+1, m, n);
29         return area;
30     }
Read full article from Find the number of islands | GeeksforGeeks

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