1.地图分析

解题思路
此题是一个标准的广度优先题目。
基本思路就是不断模拟从陆地向海洋扩张的最长距离:
查找初始所有陆地坐标,并进行判断是否为空或长度与grid大小一致,满足条件即输出-1
定义一个判断给定坐标值是否有效的辅助函数:isValid(x, y)
定义一个4向delta列表,用于从当前坐标生成新坐标,并初始化depth=-1
从当前陆地坐标列表开始向外扩张探索:
对于每个待搜索的陆地坐标,依次生成4个方向新的坐标值
若新坐标值尚未探索到,则加入到待探索列表tmp,并将其"填充"为陆地(即赋值为1),避免重复探索
若当前深度所有陆地周边仍有待探索的海洋(即tmp不为空),则继续探测
最后,需特殊考虑depth初值问题:由于陆地初始值是已有深度,当其探索一层后方可赋值为1,所以其初始值实际上应为-1.
class Solution:
def maxDistance(self, grid: List[List[int]]) -> int:
# m-行数,n-列数
m, n = len(grid), len(grid[0])
# 找到陆地坐标
nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
print(nodes)
if not nodes or len(nodes)==m*n:#是否为纯陆地或纯海洋
return -1
# 判定指定坐标是否有效
def isValid(x, y):
return 0<=x<m and 0<=y<n
# 四个移动方向
delta = [(0, 1), (0, -1), (1, 0), (-1, 0)]
depth = -1
while nodes:
depth += 1
tmp = [] # 存储探索海洋目标
for x, y in nodes: # 对当前每个待探坐标分别处理4个方向
for d in delta:
newx, newy = x+d[0], y+d[1]
if isValid(newx, newy) and not grid[newx][newy]:
tmp.append((newx, newy))
grid[newx][newy] = 1 # 已经探测到的改成陆地
nodes = tmp
return depth
来看看细节:
grid = [[1,0,1],[0,0,0],[1,0,1]]
m, n = len(grid), len(grid[0])
nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
print('nodes:', nodes)
for x, y in nodes:
print('x:', x)
print('y:', y)


class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
# 方向数组,它表示了相对于当前位置的 4 个方向的横、纵坐标的偏移量,这是一个常见的技巧
directions = [(-1, 0), (0, -1), (1, 0), (0, 1)]
m = len(grid)
# 特判
if m == 0:
return 0
n = len(grid[0])
marked = [[False for _ in range(n)] for _ in range(m)]
count = 0
for i in range(m):
for j in range(n):
if not marked[i][j] and grid[i][j] == '1':
queue = deque()
queue.append((i, j))
# 注意:这里要标记上已经访问过
marked[i][j] = True
while queue:
cur_x, cur_y = queue.popleft()
for d in directions:
new_i, new_j = cur_x + d[0], cur_y + d[1]
# 如果不越界、没有被访问过、并且还要是陆地,我就继续放入队列,放入队列的同时,
# 要记得标记已经访问过
if 0 <= new_i < m and 0 <= new_j <n and not marked[new_i][new_j] and grid[new_i][new_j] == '1':
queue.append((new_i, new_j))
marked[new_i][new_j] = True
count += 1
return count
以下是错误的,不知道为啥是错的
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
m, n = len(grid), len(grid[0])
# 找到陆地坐标
nodes = [(i, j) for i in range(m) for j in range(n) if grid[i][j]]
print(nodes)
delta = [(0, 1), (0, -1), (1, 0), (-1, 0)]
count = 0
marked = [[False for _ in range(m)] for _ in range(n)]
print(marked)
while nodes:
count += 1
tmp = []
for x, y in nodes:
for d in delta:
newx, newy = x+d[0], y+d[1]
# 只要是陆地,且没有被访问过的,就可以使用 BFS 发现与之相连的陆地,并进行标记
if 0<=m<newx and 0<=n<newy and not marked[newx][newy] and grid[newx][newy]:
tmp.append((newx, newy))
marked[newx][newy] = True
nodes = tmp
return count