给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。
岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。
此外,你可以假设该网格的四条边均被水包围。

示例 1:

输入:grid = [
[“1”,”1”,”1”,”1”,”0”],
[“1”,”1”,”0”,”1”,”0”],
[“1”,”1”,”0”,”0”,”0”],
[“0”,”0”,”0”,”0”,”0”]
]
输出:1
示例 2:

输入:grid = [
[“1”,”1”,”0”,”0”,”0”],
[“1”,”1”,”0”,”0”,”0”],
[“0”,”0”,”1”,”0”,”0”],
[“0”,”0”,”0”,”1”,”1”]
]
输出:3

提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] 的值为 ‘0’ 或 ‘1’

解法一:DFS

遍历地图中所有的节点,每当遇到一个陆地时,就用DFS将该陆地所在岛屿上的所有陆地都标记为已访问。

  1. class Solution:
  2. def numIslands(self, grid: List[List[str]]) -> int:
  3. m, n = len(grid), len(grid[0])
  4. ans = 0
  5. for i in range(m):
  6. for j in range(n):
  7. if grid[i][j] == '1':
  8. ans += 1
  9. stack = [(i, j)]
  10. while stack:
  11. x, y = stack.pop()
  12. # mark the node as visited
  13. grid[x][y] = '2'
  14. if x > 0 and grid[x-1][y] == '1':
  15. stack.append((x-1, y))
  16. if x < m - 1 and grid[x+1][y] == '1':
  17. stack.append((x+1, y))
  18. if y > 0 and grid[x][y-1] == '1':
  19. stack.append((x, y-1))
  20. if y < n - 1 and grid[x][y+1] == '1':
  21. stack.append((x, y+1))
  22. return ans

解法二:BFS

将DFS的部分改成队列即可实现BFS。

解法三:Union Find

使用并查集root记录每个节点的root索引。注意find时候会把寻找根节点时沿途的节点root索引都设置为真正的根(i == root[i])。

  1. class Solution:
  2. def numIslands(self, grid: List[List[str]]) -> int:
  3. m, n = len(grid), len(grid[0])
  4. uf = UnionFind(grid)
  5. waters = 0
  6. for i in range(m):
  7. for j in range(n):
  8. if grid[i][j] == '0':
  9. waters += 1
  10. continue
  11. current = n * i + j
  12. if i > 0 and grid[i-1][j] == '1':
  13. neighbor = n * (i - 1) + j
  14. uf.union(neighbor, current)
  15. if i < m - 1 and grid[i+1][j] == '1':
  16. neighbor = n * (i + 1) + j
  17. uf.union(neighbor, current)
  18. if j > 0 and grid[i][j-1] == '1':
  19. neighbor = n * i + j - 1
  20. uf.union(neighbor, current)
  21. if j < n - 1 and grid[i][j+1] == '1':
  22. neighbor = n * i + j + 1
  23. uf.union(neighbor, current)
  24. # 水应该从ans中减去
  25. return uf.get_count() - waters
  26. class UnionFind:
  27. def __init__(self, grid):
  28. m, n = len(grid), len(grid[0])
  29. self.root = [i for i in range(m * n)]
  30. self.count = m * n
  31. def find(self, x):
  32. if x == self.root[x]:
  33. return x
  34. self.root[x] = self.find(self.root[x])
  35. return self.root[x]
  36. def union(self, x, y):
  37. """Merge x to y"""
  38. root_x = self.find(x)
  39. root_y = self.find(y)
  40. if root_x != root_y:
  41. self.root[root_x] = root_y
  42. self.count -= 1
  43. def get_count(self):
  44. return self.count