最大加号标志Java
文章发布较早,内容可能过时,阅读注意甄别。
# 题目
在一个 n x n 的矩阵 grid 中,除了在数组 mines 中给出的元素为 0,其他每个元素都为 1。mines[i] = [xi, yi]表示 grid[xi][yi] == 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 < n
- 每一对 (xi, yi) 都 不重复
# 思路
动态规划
# 解法
class Solution {
public int orderOfLargestPlusSign(int n, int[][] mines) {
int ans = 0;
boolean[][] zero = new boolean[n][n];
for (int[] mine : mines) zero[mine[0]][mine[1]] = true;
int[][] up = new int[n][n], left = new int[n][n],
down = new int[n][n], right = new int[n][n];
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
if (zero[i][j]) continue;
up[i][j] = left[i][j] = 1;
if (i > 0) up[i][j] += up[i - 1][j];
if (j > 0) left[i][j] += left[i][j - 1];
}
}
for (int i = n - 1; i >= 0; --i) {
for (int j = n - 1; j >= 0; --j) {
if (zero[i][j]) continue;
down[i][j] = right[i][j] = 1;
if (i < n - 1) down[i][j] += down[i + 1][j];
if (j < n - 1) right[i][j] += right[i][j + 1];
ans = Math.max(ans,
Math.min(up[i][j],
Math.min(left[i][j],
Math.min(down[i][j],
right[i][j]))));
}
}
return ans;
}
}
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
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
# 总结
- 分析出几种情况,然后分别对各个情况实现