每日两题 T9

时间:2022-07-22
本文章向大家介绍每日两题 T9,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

算法

LeetCode T1162. 地图分析[1]

描述

你现在手里有一份大小为 N x N 的『地图』(网格) grid,上面的每个『区域』(单元格)都用 01 标记好了。其中 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 <= 100grid[i][j] 不是 0 就是 1

分析

本题实现方法很多,可使用 宽度优先搜索多源最短路动态规划

多源最短路的示例图,引自LeetCode

我们知道对于每个海洋区域 (x, y)(x,y),离它最近的陆地区域到它的路径要么从上方或者左方来,要么从右方或者下方来。考虑做两次动态规划,第一次从左上到右下,第二次从右下到左上,记 f(x, y)f(x,y) 为 (x, y)(x,y) 距离最近的陆地区域的曼哈顿距离,则我们可以推出这样的转移方程:

我们初始化的时候把陆地的 f 值全部预置为 0,海洋的 f 全部预置为 INF,做完两个阶段的动态规划后,我们在所有的不为零的 f[i][j] 中比一个最大值即可,如果最终比较出的最大值为 INF,就返回 -1。

代码


/**
 * @param {number[][]} grid
 * @return {number}
 */
var maxDistance = function (grid) {
    if (grid.length < 2) return -1
    let n = grid.length;
    // 创建 dp 状态矩阵
    let dp = new Array(n);
    for (let i = 0; i < n; i++) {
        dp[i] = new Array(n);
    }

    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            dp[i][j] = (grid[i][j] ? 0 : Infinity);
        }
    }
    // 从左上向右下遍历
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (grid[i][j]) continue
            if (i - 1 >= 0) dp[i][j] = Math.min(dp[i][j], dp[i - 1][j] + 1);
            if (j - 1 >= 0) dp[i][j] = Math.min(dp[i][j], dp[i][j - 1] + 1);
        }
    }
    // 从右下向左上遍历
    for (let i = n - 1; i >= 0; i--) {
        for (let j = n - 1; j >= 0; j--) {
            if (grid[i][j]) continue
            if (i + 1 < n) dp[i][j] = Math.min(dp[i][j], dp[i + 1][j] + 1);
            if (j + 1 < n) dp[i][j] = Math.min(dp[i][j], dp[i][j + 1] + 1);
        }
    }
    let ans = -1;
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            if (!grid[i][j]) ans = Math.max(ans, dp[i][j]);
        }
    }
    if (ans === Infinity) {
        return -1
    } else {
        return ans
    }
};

前端

为什么通常在发送数据埋点请求的时候使用的是 1x1 像素的透明 gif 图片?

1.跨域友好支持,执行过程无阻塞2.利用空白gif或1x1 px的img是互联网广告或网站监测方面常用的手段,简单、安全、相比PNG/JPG体积小,1px 透明图,对网页内容的影响几乎没有影响,这种请求用在很多地方,比如浏览、点击、热点、心跳、ID颁发等等3.图片请求不占用 Ajax 请求限额4.GIF的最低合法体积最小(最小的BMP文件需要74个字节,PNG需要67个字节,而合法的GIF,只需要43个字节)

References

[1] 1162. 地图分析: https://leetcode-cn.com/problems/as-far-from-land-as-possible/