classSolution: defnumIslands(self, grid: List[List[str]]) -> int: q, ans = deque(), 0 m, n = len(grid), len(grid[0]) visited = [[False] * n for _ inrange(m)]
defsearch(i, j): visited[i][j] = True
# 如果目标并非陆地则直接返回找到 0 个小岛 if grid[i][j] != "1": return0
# 初始化队列准备开始 BFS q.append([i, j])
while q: # 拿到下一个坐标 x, y = q.popleft() # 遍历 4 个方向的坐标 for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]: # 计算相邻坐标 x1, y1 = x + dx, y + dy # 如果相邻坐标不存在或已经遍历过则跳过 if x1 < 0or x1 == m or y1 < 0or y1 == n or visited[x1][y1]: continue # 检查是否存在相邻的陆地 if grid[x1][y1] == "1": q.append([x1, y1]) # 标记已遍历 visited[x1][y1] = True
# 所有小岛范围的陆地遍历结束,返回找到 1 个小岛 return1
for i inrange(m): for j inrange(n): ifnot visited[i][j]: ans += search(i, j)
return ans
思路 BFS + 优化空间复杂度
这个版本在上一个思路上直接修改输入数据来优化额外的空间使用。具体看代码注释。
classSolution: defnumIslands(self, grid: List[List[str]]) -> int: q, ans = deque(), 0 m, n = len(grid), len(grid[0])
defsearch(i, j): # 标记已遍历 grid[i][j] = "" # 初始化 BFS 队列 q.append([i, j]) while q: # 拿到下一个坐标 x, y = q.popleft() # 遍历 4 个方向的坐标 for dx, dy in [(1, 0), (0, 1), (-1, 0), (0, -1)]: # 计算相邻坐标 x1, y1 = x + dx, y + dy # 如果相邻坐标不存在或不为陆地则跳过 if x1 < 0or x1 == m or y1 < 0or y1 == n or grid[x1][y1] != "1": continue # 保存坐标进行下一轮搜索 q.append([x1, y1]) # 标记已遍历 grid[x1][y1] = ""
for i inrange(m): for j inrange(n): if grid[i][j] == "1": ans += 1 search(i, j)
classSolution: defnumIslands(self, grid: List[List[str]]) -> int: m, n = len(grid), len(grid[0]) par = [-1] * (m * n)
deffind(x): """查找并更新起始位置""" if par[x] == x: return x par[x] = find(par[x]) return par[x]
defunion(x, y): """合并2个集合""" f1, f2 = find(x), find(y) if f1 != f2: par[f1] = par[f2]
for i inrange(m): for j inrange(n): if grid[i][j] == "1": par[i * n + j] = i * n + j if i - 1 >= 0and grid[i - 1][j] == "1": union(i * n + j, (i - 1) * n + j) if j - 1 >= 0and grid[i][j - 1] == "1": union(i * n + j, i * n + j - 1)
res = set() for i inrange(len(par)): if par[i] != -1: res.add(find(i))