js + leetcode刷题:No.1162 地图分析

思路:所有初始陆地格子,作为0层的节点;BFS遍历四个方向节点;当遍历结束时,当前遍历层数就是最远距离

该题目的标签为“图”、“广度优先搜索(BFS)”,图的BFS 需要使用队列,代码框架是这样子的(伪代码):

while queue 非空:
	node = queue.pop()
    for node 的所有相邻结点 m:
        if m 未访问过:
            queue.push(m)

根据改题分析,要计算最远的距离,就是从当前已有的陆地节点开始向四个方向延伸,如果有发现不为0的记录一下,继续延伸,延伸的次数即为最远的距离。

题目:

  1. 地图分析
    你现在手里有一份大小为 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
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值