200. Number of Islands
2/14/2018 update
Union find solution:
--------------------------------------------------------------------------------
Problem:
Union find solution:
- push all '1's to union set
- count # of '1's.
- iterate through grid, if found '1', go 4 directions, union '1's.
- subtract count by 1 if '1' can be connected.
class Solution { class Union_Find { private int[] father; public int count = 0; public Union_Find(char[][] grid, int m, int n) { father = new int[m*n]; for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { count++; father[i*n + j] = i*n + j; } } } public void connect(int a, int b) { int root_a = find(a); int root_b = find(b); if (root_a != root_b) { father[root_a] = root_b; count--; } } public int find(int n) { if (father[n] == n) return n; return father[n] = find(father[n]); } public boolean query(int a, int b) { int root_a = find(a); int root_b = find(b); return root_a == root_b; } } public int numIslands(char[][] grid) { if (grid == null || grid.length == 0 || grid[0].length == 0) return 0; int[][] dirs = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; int m = grid.length; int n = grid[0].length; Union_Find uf = new Union_Find(grid, m, n); for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { int index = i*n + j; for (int[] d : dirs) { int r = i + d[0]; int c = j + d[1]; if (r >= 0 && r < m && c >= 0 && c < n && grid[r][c] == '1') { uf.connect(index, r*n + c); } } } } return uf.count; } }
--------------------------------------------------------------------------------
Problem:
Given a 2d grid map of
'1'
s (land) and '0'
s (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Example 1:
11110 11010 11000 00000
Answer: 1
Example 2:
11000 11000 00100 00011
Answer: 3
Analysis:
Use bfs, when encounters 1,count ++ do bfs. mark visited char to 0.
Mark 0 right after adding item to queue. If not, would exceed time limit.
Can avoid using coordinate class by storing int (x * n + 7) to queue. Restore can be achieved by x = index / n, y = index % n.
Solution:
class Solution { class Coordinate { int x, y; public Coordinate(int x, int y) { this.x = x; this.y = y; } } public int numIslands(char[][] grid) { if (grid == null || grid.length == 0 || grid[0].length == 0) return 0; int m = grid.length; int n = grid[0].length; int res = 0; int[] dx = new int[]{0, 0, 1, -1}; int[] dy = new int[]{1, -1, 0, 0}; Queue<Coordinate> queue = new LinkedList<>(); for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { if (grid[i][j] == '1') { res++; queue.add(new Coordinate(i, j)); grid[i][j] = '0'; while (!queue.isEmpty()) { Coordinate cur = queue.remove(); int x = cur.x; int y = cur.y; for (int q = 0; q < 4; q++) { int newx = x + dx[q]; int newy = y + dy[q]; if (newx < 0 || newx >= m || newy < 0 || newy >= n || grid[newx][newy] == '0') { continue; } queue.add(new Coordinate(newx, newy)); grid[newx][newy] = '0'; } } } } } return res; } }
评论
发表评论