LeetCode 每日 1 题:最大加号标志

46 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第 23 天,点击查看活动详情

最大加号标志

原题地址

在一个 n x n 的矩阵 grid 中,除了在数组 mines 中给出的元素为 0,其他每个元素都为 1mines[i]=[xi,yi]mines[i] = [x_i, y_i]表示 grid[xi][yi]==0grid[x_i][y_i] == 0

返回  grid 中包含 1 的最大的 轴对齐 加号标志的阶数 。如果未找到加号标志,则返回 0

一个 k 阶由 1 组成的 “轴对称”加号标志 具有中心网格 grid[r][c] == 1 ,以及4个从中心向上、向下、向左、向右延伸,长度为 k-1,由 1 组成的臂。注意,只有加号标志的所有网格要求为 1 ,别的网格可能为 0 也可能为 1

示例 1:

输入: n = 5, mines = [[4, 2]]
输出: 2
解释: 在上面的网格中,最大加号标志的阶只能是2。一个标志已在图中标出。

示例 2:

输入: n = 1, mines = [[0, 0]]
输出: 0
解释: 没有加号标志,返回 0

提示:

  • 1 <= n <= 500
  • 1 <= mines.length <= 5000
  • 0<=xi,yi <n0 <= x_i, y_i < n
  • 每一对 (xi,yi)(x_i, y_i) 都 不重复

思路分析

  1. 首先将 grid 建立起来,初始值每个都为 0,然后将 mines 中对应的坐标项的值改成 1
  2. 题目的要求转换思路就是在 n*n 的矩阵中找到最大的加号,转换成从步骤1中构建的 grid 中寻找最大的加号;
  3. 思路就是遍历矩阵,然后计算每个点上下左右所能延伸的最小长度,在遍历过程中,分上下左右四个方向来寻找需要的长度,然后取每个点最小长度的最大值返回即可。

AC 代码

/**
 * @param {number} n
 * @param {number[][]} mines
 * @return {number}
 */
var orderOfLargestPlusSign = function(n, mines) {
    const grid = Array.from({ length: n }, item => new Array(n).fill(1))
    
    for (const [x, y] of mines) {
        grid[x][y] = 0
    }

    let result = 0
    for (let i = 0; i < n; i++) {
        for (let j = 0; j < n; j++) {
            let left = 0, right = 0, top = 0, bottom = 0
            while (j + left >= 0 && grid[i][j + left] !== 0) left--
            while (j + right < n && grid[i][j + right] !== 0) right++
            while (i + top >= 0 && grid[i + top][j] !== 0) top--
            while (i + bottom < n && grid[i + bottom][j] !== 0) bottom++
            result = Math.max(result, Math.min(-left, right, -top, bottom))
        }
    }
    return result 
};

结果:

  • 执行结果: 通过
  • 执行用时:2260 ms, 在所有 JavaScript 提交中击败了8.40%的用户
  • 内存消耗:47.8 MB, 在所有 JavaScript 提交中击败了89.33%的用户
  • 通过测试用例:56 / 56

END