思路:所有初始陆地格子,作为0层的节点;BFS遍历四个方向节点;当遍历结束时,当前遍历层数就是最远距离
该题目的标签为“图”、“广度优先搜索(BFS)”,图的BFS 需要使用队列,代码框架是这样子的(伪代码):
while queue 非空:
node = queue.pop()
for node 的所有相邻结点 m:
if m 未访问过:
queue.push(m)
根据改题分析,要计算最远的距离,就是从当前已有的陆地节点开始向四个方向延伸,如果有发现不为0的记录一下,继续延伸,延伸的次数即为最远的距离。
题目:
- 地图分析
你现在手里有一份大小为 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。
示例 2:
输入:[[1,0,0],[0,0,0],[0,0,0]]
输出:4
解释:
海洋区域 (2, 2) 和所有陆地区域之间的距离都达到最大,最大距离为 4。
提示:
1 <= grid.length == grid[0].length <= 100
grid[i][j] 不是 0 就是 1
解法:
/**
* @param {number[][]} grid
* @return {number}
*/
var maxDistance = function(grid) {
let result = -1, // 距离
land = [], // 存放陆地的队列
row = grid.length, // 行数
col = grid[0].length // 列数
// 所有陆地入列
for(let i = 0; i < row; i++){
for(let j = 0; j < col; j++){
if(grid[i][j] === 1){
land.push([i,j])
}
}
}
// 全是海洋或陆地
if(land.length === 0 || land.length === row*col) return -1
// 对每一块陆地进行BFS,对每一块遍历过的海洋标记为陆地
while(land.length > 0){
let size = land.length // 记录当前层陆地的个数
while(size > 0){
size--
let cur = land.shift() // 第一个入队的陆地
// 四个方向
let directions = [[-1,0],[0,1],[1,0],[0,-1]]
for(let i = 0; i < 4; i++){
let r = cur[0] + directions[i][0],
c = cur[1] + directions[i][1]
// 超出界限
if(r < 0 || r > col-1 || c < 0 || c > row-1 || grid[r][c] === 1){
continue
}
// 如果是海洋,标记陆地,计入队列,距离+1
if(grid[r][c] === 0){
grid[r][c] = 1
land.push([r,c])
}
}
}
result++
}
return result
}