题目
你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 0 和 1 标记好了。其中 0 代表海洋,1 代表陆地,你知道距离陆地区域最远的海洋区域是是哪一个吗?请返回该海洋区域到离它最近的陆地区域的距离。
我们这里说的距离是『曼哈顿距离』( Manhattan Distance):(x0, y0) 和 (x1, y1) 这两个区域之间的距离是 |x0 - x1| + |y0 - y1| 。
如果我们的地图上只有陆地或者海洋,请返回 -1。
示例 1:
输入:[[1,0,1],[0,0,0],[1,0,1]]
输出:2
解释:
海洋区域 (1, 1) 和所有陆地区域之间的距离都达到最大,最大距离为 2。
解法一(海洋为中心扩张)
思路:以海洋区域坐标为中心点,向四周进行递归查找,其中最短距离的值即为当前海洋区域的距离,遍历所有海洋区域后,记录最大的距离。
为了减少单个海洋区域遍历时的重复递归,在递归中XY仅沿一个方向行走,因此最终划分为四个现象方向。
当前解法有种暴力法的味道,当然也可以添加访问标志,来进一步减少重复访问。
- 仅对海洋区域为中心进行计算,忽略大陆区域
- 单个现象的递归中,分别沿XY方向的递归,分别沿4个现象递归后的最小值即为当前海洋的距离
- 对所有海洋中心遍历后,其中最大的距离即为解
- 时间复杂度:O(N4)
- 空间复杂度:O(1)
# author: suoxd123@126.com
class Solution:
def maxDistance(self, grid: List[List[int]]) -> int:
row, col = len(grid), len(grid[0])
maxRst, MAX_TMP, = 0, row + col
tmpSum = sum([sum(v) for v in grid])
if tmpSum in (0, row * col): #全是陆地或海洋
return -1
for i in range(0,row):
for j in range(0,col):
if grid[i][j] == 1:#忽略陆地区域
continue
# 递归:计算单个海洋区域,在一个现象内的最近陆地距离
def findDistance(rIdx, cIdx, rDelta, cDelta)-> int:
if not(0 <= rIdx < row and 0 <= cIdx < col): # 越界检查
return MAX_TMP
if grid