[LeetCode] 2257. Count Unguarded Cells in the Grid
You are given two integers m and n representing a 0-indexed m x n grid. You are also given two 2D integer arrays guards and walls where guards[i] = [rowi, coli] and walls[j] = [rowj, colj] represent the positions of the ith guard and jth wall respectively.
A guard can see every cell in the four cardinal directions (north, east, south, or west) starting from their position unless obstructed by a wall or another guard. A cell is guarded if there is at least one guard that can see it.
Return the number of unoccupied cells that are not guarded.
Example 1:
Input: m = 4, n = 6, guards = [[0,0],[1,1],[2,3]], walls = [[0,1],[2,2],[1,4]]
Output: 7
Explanation: The guarded and unguarded cells are shown in red and green respectively in the above diagram.
There are a total of 7 unguarded cells, so we return 7.
Example 2:
Input: m = 3, n = 3, guards = [[1,1]], walls = [[0,1],[1,0],[2,1],[1,2]]
Output: 4
Explanation: The unguarded cells are shown in green in the above diagram.
There are a total of 4 unguarded cells, so we return 4.
Constraints:
1 <= m, n <= 105
2 <= m * n <= 105
1 <= guards.length, walls.length <= 5 * 104
2 <= guards.length + walls.length <= m * n
guards[i].length == walls[j].length == 2
0 <= rowi, rowj < m
0 <= coli, colj < n
All the positions in guards and walls are unique.
统计网格图中没有被保卫的格子数。
给你两个整数 m 和 n 表示一个下标从 0 开始的 m x n 网格图。同时给你两个二维整数数组 guards 和 walls ,其中 guards[i] = [rowi, coli] 且 walls[j] = [rowj, colj] ,分别表示第 i 个警卫和第 j 座墙所在的位置。一个警卫能看到 4 个坐标轴方向(即东、南、西、北)的 所有 格子,除非他们被一座墙或者另外一个警卫 挡住 了视线。如果一个格子能被 至少 一个警卫看到,那么我们说这个格子被 保卫 了。
请你返回空格子中,有多少个格子是 没被保卫 的。
思路
需要创建一个额外的 m x n 二维数组,用来记录每个格子上是否有守卫,是否有墙和是否有被警卫看到,如果都不是,则说明这个格子是没被保卫的
。
复杂度
时间O(mn)
空间O(mn)
代码
Java实现
class Solution {
int[][] dirs = new int[][] {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
public int countUnguarded(int m, int n, int[][] guards, int[][] walls) {
char[][] grid = new char[m][n];
// 标注guard和wall的位置
for (int[] g : guards) {
int x = g[0];
int y = g[1];
grid[x][y] = 'G';
}
for (int[] w : walls) {
int x = w[0];
int y = w[1];
grid[x][y] = 'W';
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
// 往guard的四个方向看
if (grid[i][j] == 'G') {
for (int[] dir : dirs) {
int x = i + dir[0];
int y = j + dir[1];
while (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] != 'G' && grid[x][y] != 'W') {
grid[x][y] = 'I';
x += dir[0];
y += dir[1];
}
}
}
}
}
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] != 'I' && grid[i][j] != 'G' && grid[i][j] != 'W') {
res++;
}
}
}
return res;
}
}