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;
}
}