Merge pull request #2325 from gggxxxx/XiongGu-branch

添加0827.最大人工岛Python3版本
This commit is contained in:
程序员Carl
2023-11-07 10:58:58 +08:00
committed by GitHub

View File

@ -284,64 +284,68 @@ class Solution {
### Python ### Python
```Python ```python
class Solution(object):
# 可能的移动方向
DIRECTIONS = [(1, 0), (-1, 0), (0, 1), (0, -1)]
def exploreIsland(self, row, col, grid, visited, island_id):
"""
从给定的单元格开始,使用深度优先搜索探索岛屿。
"""
if (row < 0 or row >= len(grid) or col < 0 or col >= len(grid[0]) or
visited[row][col] or grid[row][col] == 0):
return 0
visited[row][col] = True class Solution:
grid[row][col] = island_id def largestIsland(self, grid: List[List[int]]) -> int:
island_size = 1 visited = set() #标记访问过的位置
for dr, dc in self.DIRECTIONS: m, n = len(grid), len(grid[0])
island_size += self.exploreIsland(row + dr, col + dc, grid, visited, island_id) res = 0
return island_size island_size = 0 #用于保存当前岛屿的尺寸
directions = [[0, 1], [0, -1], [1, 0], [-1, 0]] #四个方向
islands_size = defaultdict(int) #保存每个岛屿的尺寸
def largestIsland(self, grid): def dfs(island_num, r, c):
""" visited.add((r, c))
通过最多将一个0更改为1找到可以形成的最大岛屿的大小。 grid[r][c] = island_num #访问过的位置标记为岛屿编号
""" nonlocal island_size
rows, cols = len(grid), len(grid[0]) island_size += 1
island_sizes = {} for i in range(4):
island_id = 2 # 从2开始标记岛屿因为0代表水1代表未被发现的陆地 nextR = r + directions[i][0]
is_all_land = True nextC = c + directions[i][1]
visited = [[False] * cols for _ in range(rows)] if (nextR not in range(m) or #行坐标越界
nextC not in range(n) or #列坐标越界
# 标记每个岛屿并存储其大小 (nextR, nextC) in visited): #坐标已访问
for r in range(rows): continue
for c in range(cols): if grid[nextR][nextC] == 1: #遇到有效坐标,进入下一个层搜索
dfs(island_num, nextR, nextC)
island_num = 2 #初始岛屿编号设为2 因为grid里的数据有0和1 所以从2开始编号
all_land = True #标记是否整个地图都是陆地
for r in range(m):
for c in range(n):
if grid[r][c] == 0: if grid[r][c] == 0:
is_all_land = False all_land = False #地图里不全是陆地
elif not visited[r][c] and grid[r][c] == 1: if (r, c) not in visited and grid[r][c] == 1:
island_size = self.exploreIsland(r, c, grid, visited, island_id) island_size = 0 #遍历每个位置前重置岛屿尺寸为0
island_sizes[island_id] = island_size dfs(island_num, r, c)
island_id += 1 islands_size[island_num] = island_size #保存当前岛屿尺寸
island_num += 1 #下一个岛屿编号加一
if all_land:
return m * n #如果全是陆地, 返回地图面积
# 如果整个网格是陆地,则返回其大小 count = 0 #某个位置0变成1后当前岛屿尺寸
if is_all_land: #因为后续计算岛屿面积要往四个方向遍历但某2个或3个方向的位置可能同属于一个岛
return rows * cols #所以为避免重复累加,把已经访问过的岛屿编号加入到这个集合
visited_island = set() #保存访问过的岛屿
# 计算可以通过将一个0更改为1来形成的最大岛屿 for r in range(m):
max_island_size = 0 for c in range(n):
for r in range(rows):
for c in range(cols):
if grid[r][c] == 0: if grid[r][c] == 0:
adjacent_islands = set() count = 1 #把由0转换为1的位置计算到面积里
for dr, dc in self.DIRECTIONS: visited_island.clear() #遍历每个位置前清空集合
nr, nc = r + dr, c + dc for i in range(4):
if 0 <= nr < rows and 0 <= nc < cols and grid[nr][nc] > 1: nearR = r + directions[i][0]
adjacent_islands.add(grid[nr][nc]) nearC = c + directions[i][1]
new_island_size = sum(island_sizes[island] for island in adjacent_islands) + 1 if nearR not in range(m) or nearC not in range(n): #周围位置越界
max_island_size = max(max_island_size, new_island_size) continue
if grid[nearR][nearC] in visited_island: #岛屿已访问
continue
count += islands_size[grid[nearR][nearC]] #累加连在一起的岛屿面积
visited_island.add(grid[nearR][nearC]) #标记当前岛屿已访问
res = max(res, count)
return res
return max_island_size
``` ```
<p align="center"> <p align="center">