很经典的一道题,提供三种解法:DFS,BFS,并查集
1.DFS遍历每个点,如果等于1,将其设置为0,递归遍历其周围的四个点(在矩阵范围内)。计算触发DFS结点的数目。
2.BFS遍历每个点,如果等于1,将其设置为0,用while循环加队列遍历其周围的点(在矩阵范围内),直到队列为空。计算触发BFS结点的数目。
3.并查集:构造了并查集
JAVA
class Solution { public void dfs(char[][] grid, int a, int b){ grid[a][b] = '0'; if(a-1 >= 0 && grid[a-1][b] == '1')dfs(grid, a-1, b); if(a+1 < grid.length && grid[a+1][b] == '1')dfs(grid, a+1, b); if(b-1 >= 0 && grid[a][b-1] == '1')dfs(grid, a, b-1); if(b+1 < grid[0].length && grid[a][b+1] == '1')dfs(grid, a, b+1); } public int numIslands(char[][] grid) { if(grid == null || grid.length == 0){ return 0; } int m = grid.length; int n = grid[0].length; int res = 0; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(grid[i][j] == '1'){ res++; dfs(grid, i, j); } } } return res; } }
class Solution { public int numIslands(char[][] grid) { if(grid == null || grid.length == 0){ return 0; } int m = grid.length; int n = grid[0].length; int res = 0; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(grid[i][j] == '1'){ res++; grid[i][j] = '0'; Queue<Integer> queue = new LinkedList<>(); queue.add(i*n+j);//!!!对坐标的保存 while(!queue.isEmpty()){ int id = queue.remove(); int row = id / n; int col = id % n; if(row-1 >= 0 && grid[row-1][col] == '1'){ grid[row-1][col] = '0'; queue.add((row-1)*n + col); } if(row+1 < m && grid[row+1][col] == '1'){ grid[row+1][col] = '0'; queue.add((row+1)*n + col); } if(col-1 >= 0 && grid[row][col-1] == '1'){ grid[row][col-1] = '0'; queue.add(row*n + col-1); } if(col+1 < n && grid[row][col+1] == '1'){ grid[row][col+1] = '0'; queue.add(row*n + col+1); } } } } } return res; } }
class Solution { class UnionFind { int count; // # of connected components int[] parent; int[] rank; public UnionFind(char[][] grid) { // for problem 200 count = 0; int m = grid.length; int n = grid[0].length; parent = new int[m * n]; rank = new int[m * n]; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (grid[i][j] == '1') { parent[i * n + j] = i * n + j; ++count; } rank[i * n + j] = 0; } } } public int find(int i) { // path compression if (parent[i] != i) parent[i] = find(parent[i]); return parent[i]; } public void union(int x, int y) { // union with rank int rootx = find(x); int rooty = find(y); if (rootx != rooty) { if (rank[rootx] > rank[rooty]) { parent[rooty] = rootx; } else if (rank[rootx] < rank[rooty]) { parent[rootx] = rooty; } else { parent[rooty] = rootx; rank[rootx] += 1; } --count; } } public int getCount() { return count; } } public int numIslands(char[][] grid) { if (grid == null || grid.length == 0) { return 0; } int nr = grid.length; int nc = grid[0].length; int num_islands = 0; UnionFind uf = new UnionFind(grid); for (int r = 0; r < nr; ++r) { for (int c = 0; c < nc; ++c) { if (grid[r][c] == '1') { grid[r][c] = '0'; if (r - 1 >= 0 && grid[r-1][c] == '1') { uf.union(r * nc + c, (r-1) * nc + c); } if (r + 1 < nr && grid[r+1][c] == '1') { uf.union(r * nc + c, (r+1) * nc + c); } if (c - 1 >= 0 && grid[r][c-1] == '1') { uf.union(r * nc + c, r * nc + c - 1); } if (c + 1 < nc && grid[r][c+1] == '1') { uf.union(r * nc + c, r * nc + c + 1); } } } } return uf.getCount(); } }
Python3
class Solution: def numIslands(self, grid: List[List[str]]) -> int: if not grid or not grid[0]: return 0 res = 0 m = len(grid) n = len(grid[0]) for x in range(m): for y in range(n): if grid[x][y] == '1': self.dfs(grid, x, y) res += 1 return res def dfs(self, grid, a, b): grid[a][b] = '0' for i, j in [(a+1, b), (a-1, b), (a, b-1), (a, b+1)]: if 0 <= i < len(grid) and 0 <= j < len(grid[0]) and grid[i][j] == '1': self.dfs(grid, i, j)
class Solution: def numIslands(self, grid: List[List[str]]) -> int: if not grid or not grid[0]: return 0 res = 0 m = len(grid) n = len(grid[0]) for x in range(m): for y in range(n): if grid[x][y] == '1': res += 1 queue = [] queue.append((x,y)) while queue: row, col = queue.pop(0) if row-1 >= 0 and grid[row-1][col] == '1': grid[row-1][col] = '0' queue.append((row-1,col)) if row+1 < m and grid[row+1][col] == '1': grid[row+1][col] = '0' queue.append((row+1,col)) if col-1 >= 0 and grid[row][col-1] == '1': grid[row][col-1] = '0' queue.append((row,col-1)) if col+1 < n and grid[row][col+1] == '1': grid[row][col+1] = '0' queue.append((row,col+1)) return res