Keshawn_lu's Blog

Leetcode 764. 最大加号标志

字数统计: 616阅读时长: 3 min
2022/11/09 Share

题目简介:

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

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

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

示例 1:

plus1-grid

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

提示:

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

思路:

动态规划,以每个点为中心,从上左下右四个方向延伸,四个方向中最短的路径长度(即最少的1)则为该点的阶。

将所有点遍历完成后,返回最大值即可。

tip:

  • 利用dp[i][j][0...3]来表示四个方向的dp数组

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
class Solution {
public:
int orderOfLargestPlusSign(int n, vector<vector<int>>& mines) {

vector<vector<int>> grid(n, vector<int>(n, 1));

for(auto& item : mines)
grid[item[0]][item[1]] = 0;

vector<vector<vector<int>>> dp(n, vector<vector<int>>(n,
vector<int>(4)));

int res = 0;

for(int i = 0; i < n; i++){

//left
for(int j = 0; j < n; j++){

if(j == 0)
dp[i][j][0] = (grid[i][j] == 1) ? 1 : 0;

else if(grid[i][j] == 1)
dp[i][j][0] = 1 + dp[i][j - 1][0];
}

//right
for(int j = n - 1; j >= 0; j--){

if(j == n - 1)
dp[i][j][1] = (grid[i][j] == 1) ? 1 : 0;

else if(grid[i][j] == 1)
dp[i][j][1] = 1 + dp[i][j + 1][1];
}
}


for(int j = 0; j < n; j++){

//up
for(int i = n - 1; i >= 0; i--){

if(i == n - 1)
dp[i][j][2] = (grid[i][j] == 1) ? 1 : 0;

else if(grid[i][j] == 1)
dp[i][j][2] = 1 + dp[i + 1][j][2];
}

//down
for(int i = 0; i < n; i++){

if(i == 0)
dp[i][j][3] = (grid[i][j] == 1) ? 1 : 0;

else if(grid[i][j] == 1)
dp[i][j][3] = 1 + dp[i - 1][j][3];


res = max(res, min(min(min(dp[i][j][0], dp[i][j][1]), dp[i][j][2]),
dp[i][j][3])); //四个方向都已遍历完
}
}

return res;
}
};
CATALOG
  1. 1. 题目简介:
  2. 2. 思路:
  3. 3. 代码如下: