目录
1. 题目描述
在给定的二维二进制数组 A
中,存在两座岛。(岛是由四面相连的 1
形成的一个最大组。)
现在,我们可以将 0
变为 1
,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0
的最小数目。(可以保证答案至少是 1
。)
示例 1:
输入:A = [[0,1],[1,0]] 输出:1
示例 2:
输入:A = [[0,1,0],[0,0,0],[0,0,1]] 输出:2
示例 3:
输入:A = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]] 输出:1
提示:
2 <= A.length == A[0].length <= 100
A[i][j] == 0
或A[i][j] == 1
2. 解题分析
最短路径问题。广度优先搜索。
只不过不是从一点出发到另一个点的最短路径,而是从一个区域到另一个区域的最短路径,因此是多源多目标的最短路径问题。
从一个岛屿的最外围格点并行出发,以广度优先搜索的方式向外推进,最先碰到另一个岛屿的外围格点时的距离即为最短距离。
首先需要搜索第一个岛屿(可以遍历grid搜索第一个陆地格点,以该陆地格点所在岛屿为第一个岛屿,即为岛屿1)
其次,搜索(BFS或DFS均可)遍历岛屿1的所有格点,并将它的所有最外围格点(即至少跟一个海洋格点邻接的陆地个点)加入队列
第三,开始常规的BFS搜索,直到第一个属于岛屿2的陆地格点。此时的层数即为所求最短距离
关于多源BFS也可以参考Leetcode1162. 地图分析(medium,BFS)。
3. 代码实现
from typing import List
from collections import deque
class Solution:
def shortestBridge(self, grid: List[List[int]]) -> int:
# print(grid)
R,C = len(grid),len(grid[0])
offset = [(1,0),(0,1),(-1,0),(0,-1)]
# Search for the first land grid
flag = False
for r in range(R):
for c in range(C):
if grid[r][c] == 1:
flag = True
break
if flag:
break
# print(r,c)
# Start from (r,c) to tranverse island1 and put the outest land grid of it into queue
q = deque([(r,c)])
q2 = deque([(r,c,0)]) # For the later Multi-Source BFS
visited = set([(r,c)])
while len(q) > 0:
r,c = q.popleft()
for ofst in offset:
x,y = r+ofst[0], c+ofst[1]
if 0<=x<R and 0<=y<C and grid[x][y]==1 and (x,y) not in visited:
visited.add((x,y))
q.append((x,y))
# Whether (x,y) is the outest land grid of the island1?
for ofst in offset:
x1,y1 = x+ofst[0], y+ofst[1]
if 0<=x1<R and 0<=y1<C and grid[x1][y1]==0:
q2.append((x,y,0))
break
# print(q2,visited)
# Multi-source BFS start from q2
if len(q2) == 0: return 0
while len(q2) > 0:
r,c,layer = q2.popleft()
# print(r,c,layer,visited)
for ofst in offset:
x,y = r+ofst[0], c+ofst[1]
# print(r,c,x,y)
if 0<=x<R and 0<=y<C and (x,y) not in visited:
if grid[x][y]==0:
q2.append((x,y,layer+1))
visited.add((x,y))
else:
return layer
return -1
if __name__ == '__main__':
sln = Solution()
A = [[0,1],[1,0]]
print(sln.shortestBridge(A))
A = [[0,1,0],[0,0,0],[0,0,1]]
print(sln.shortestBridge(A))
A = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
print(sln.shortestBridge(A))
执行用时:160 ms, 在所有 Python3 提交中击败了60.39%的用户
内存消耗:16.1 MB, 在所有 Python3 提交中击败了85.82%的用户
其实寻找岛屿1时使用深度优先搜索可能效率会更高一些。
回到主目录:笨牛慢耕的Leetcode解题笔记(动态更新。。。)