61
61
62
62
<!-- 这里可写通用的实现逻辑 -->
63
63
64
- 哈希表。
64
+ ** 方法一: 哈希表**
65
65
66
- 假设一盏灯的坐标为 ` (x, y) ` ,那么它所在的行的数值为 x ,列的数值为 y ,正对角线的数值为 x-y,反对角线的数值为 x+y。确定某一直线的唯一数值标识后,我们就可以通过哈希表来记录某一直线所拥有的灯的数目。
66
+ 假设一盏灯的坐标为 $ (x, y)$ ,那么它所在的行的数值为 $x$ ,列的数值为 $y$ ,正对角线的数值为 $ x-y$ ,反对角线的数值为 $ x+y$ 。确定某一直线的唯一数值标识后,我们就可以通过哈希表来记录某一直线所拥有的灯的数目。
67
67
68
- 遍历 lamps,将当前遍历到的灯所在的行、列和正、反对角线拥有灯的数目分别加 1 。
68
+ 我们遍历数组 $ lamps$ ,将当前遍历到的灯所在的行、列和正、反对角线拥有灯的数目分别加 $1$ 。
69
69
70
- 在处理 lamps 时,需要进行去重,因为我们将重复的灯看作同一盏灯。
70
+ 注意, 在处理 $ lamps$ 时,需要进行去重,因为我们将重复的灯看作同一盏灯。
71
71
72
- 遍历 queries,判断当前查询点所在的行,列和正、反对角线是否有灯,如果有,则置 1,即该点在查询时是被照亮的。然后进行关闭操作,查找查询点所在的八近邻点及它本身是否有灯,如果有,将该点所在的行、列和正、反对角线的灯数目分别减 1,并且将灯从网格中去掉。
72
+ 接下来,我们遍历 queries,判断当前查询点所在的行,列和正、反对角线是否有灯,如果有,则置 $1$,即该点在查询时是被照亮的。然后进行关闭操作,查找查询点所在的八近邻点及它本身是否有灯,如果有,将该点所在的行、列和正、反对角线的灯数目分别减 $1$,并且将灯从网格中去掉。
73
+
74
+ 最后,返回答案数组即可。
75
+
76
+ 时间复杂度 $O(m + q)$,其中 $m$ 和 $q$ 分别为数组 $lamps$ 和 $queries$ 的长度。
73
77
74
78
<!-- tabs:start -->
75
79
79
83
80
84
``` python
81
85
class Solution :
82
- def gridIllumination (
83
- self , n : int , lamps : List[List[int ]], queries : List[List[int ]]
84
- ) -> List[int ]:
85
- points = set ()
86
- rcnt, ccnt, dgcnt, udgcnt = Counter(), Counter(), Counter(), Counter()
87
- for r, c in lamps:
88
- if (r, c) not in points:
89
- points.add((r, c))
90
- rcnt[r] += 1
91
- ccnt[c] += 1
92
- dgcnt[r - c] += 1
93
- udgcnt[r + c] += 1
86
+ def gridIllumination (self , n : int , lamps : List[List[int ]], queries : List[List[int ]]) -> List[int ]:
87
+ s = {(i, j) for i, j in lamps}
88
+ row, col, diag1, diag2 = Counter(), Counter(), Counter(), Counter()
89
+ for i, j in s:
90
+ row[i] += 1
91
+ col[j] += 1
92
+ diag1[i - j] += 1
93
+ diag2[i + j] += 1
94
94
ans = [0 ] * len (queries)
95
- for i, q in enumerate (queries):
96
- r, c = q
97
- if rcnt[r] or ccnt[c] or dgcnt[r - c] or udgcnt[r + c]:
98
- ans[i] = 1
99
- for a, b in [
100
- (0 , 1 ),
101
- (1 , 0 ),
102
- (0 , - 1 ),
103
- (- 1 , 0 ),
104
- (0 , 0 ),
105
- (1 , 1 ),
106
- (- 1 , 1 ),
107
- (1 , - 1 ),
108
- (- 1 , - 1 ),
109
- ]:
110
- x, y = r + a, c + b
111
- if (x, y) in points:
112
- points.remove((x, y))
113
- rcnt[x] -= 1
114
- ccnt[y] -= 1
115
- dgcnt[x - y] -= 1
116
- udgcnt[x + y] -= 1
95
+ for k, (i, j) in enumerate (queries):
96
+ if row[i] or col[j] or diag1[i - j] or diag2[i + j]:
97
+ ans[k] = 1
98
+ for x in range (i - 1 , i + 2 ):
99
+ for y in range (j - 1 , j + 2 ):
100
+ if (x, y) in s:
101
+ s.remove((x, y))
102
+ row[x] -= 1
103
+ col[y] -= 1
104
+ diag1[x - y] -= 1
105
+ diag2[x + y] -= 1
117
106
return ans
118
107
```
119
108
@@ -123,59 +112,147 @@ class Solution:
123
112
124
113
``` java
125
114
class Solution {
115
+ private int n;
126
116
public int [] gridIllumination (int n , int [][] lamps , int [][] queries ) {
127
- Set<Long > points = new HashSet<> ();
128
- Map<Integer , Integer > rcnt = new HashMap<> ();
129
- Map<Integer , Integer > ccnt = new HashMap<> ();
130
- Map<Integer , Integer > dgcnt = new HashMap<> ();
131
- Map<Integer , Integer > udgcnt = new HashMap<> ();
132
- for (int [] l : lamps) {
133
- int r = l[0 ], c = l[1 ];
134
- long v = r * n + c;
135
- if (! points. contains(v)) {
136
- points. add(v);
137
- rcnt. put(r, rcnt. getOrDefault(r, 0 ) + 1 );
138
- ccnt. put(c, ccnt. getOrDefault(c, 0 ) + 1 );
139
- dgcnt. put(r - c, dgcnt. getOrDefault(r - c, 0 ) + 1 );
140
- udgcnt. put(r + c, udgcnt. getOrDefault(r + c, 0 ) + 1 );
117
+ this . n = n;
118
+ Set<Long > s = new HashSet<> ();
119
+ Map<Integer , Integer > row = new HashMap<> ();
120
+ Map<Integer , Integer > col = new HashMap<> ();
121
+ Map<Integer , Integer > diag1 = new HashMap<> ();
122
+ Map<Integer , Integer > diag2 = new HashMap<> ();
123
+ for (var lamp : lamps) {
124
+ int i = lamp[0 ], j = lamp[1 ];
125
+ if (s. add(f(i, j))) {
126
+ merge(row, i, 1 );
127
+ merge(col, j, 1 );
128
+ merge(diag1, i - j, 1 );
129
+ merge(diag2, i + j, 1 );
141
130
}
142
131
}
143
- int [][] dirs
144
- = {{0 , 1 }, {1 , 0 }, {0 , - 1 }, {- 1 , 0 }, {0 , 0 }, {1 , 1 }, {- 1 , 1 }, {1 , - 1 }, {- 1 , - 1 }};
145
- int [] ans = new int [queries. length];
146
- for (int i = 0 ; i < queries. length; ++ i) {
147
- int r = queries[i][0 ], c = queries[i][1 ];
148
- if (rcnt. getOrDefault(r, 0 ) > 0 || ccnt. getOrDefault(c, 0 ) > 0
149
- || dgcnt. getOrDefault(r - c, 0 ) > 0 || udgcnt. getOrDefault(r + c, 0 ) > 0 ) {
150
- ans[i] = 1 ;
151
- for (int [] d : dirs) {
152
- int x = r + d[0 ], y = c + d[1 ];
153
- long v = x * n + y;
154
- if (x < 0 || x >= n || y < 0 || y >= n || ! points. contains(v)) {
132
+ int m = queries. length;
133
+ int [] ans = new int [m];
134
+ for (int k = 0 ; k < m; ++ k) {
135
+ int i = queries[k][0 ], j = queries[k][1 ];
136
+ if (exist(row, i) || exist(col, j) || exist(diag1, i - j) || exist(diag2, i + j)) {
137
+ ans[k] = 1 ;
138
+ }
139
+ for (int x = i - 1 ; x <= i + 1 ; ++ x) {
140
+ for (int y = j - 1 ; y <= j + 1 ; ++ y) {
141
+ if (x < 0 || x >= n || y < 0 || y >= n || ! s. contains(f(x, y))) {
155
142
continue ;
156
143
}
157
- points. remove(v);
158
- rcnt. put(x, rcnt. get(x) - 1 );
159
- if (rcnt. get(x) == 0 ) {
160
- rcnt. remove(x);
161
- }
162
- ccnt. put(y, ccnt. get(y) - 1 );
163
- if (ccnt. get(y) == 0 ) {
164
- ccnt. remove(y);
165
- }
166
- dgcnt. put(x - y, dgcnt. get(x - y) - 1 );
167
- if (dgcnt. get(x - y) == 0 ) {
168
- dgcnt. remove(x - y);
169
- }
170
- udgcnt. put(x + y, udgcnt. get(x + y) - 1 );
171
- if (udgcnt. get(x + y) == 0 ) {
172
- udgcnt. remove(x + y);
144
+ s. remove(f(x, y));
145
+ merge(row, x, - 1 );
146
+ merge(col, y, - 1 );
147
+ merge(diag1, x - y, - 1 );
148
+ merge(diag2, x + y, - 1 );
149
+ }
150
+ }
151
+ }
152
+ return ans;
153
+ }
154
+
155
+ private void merge (Map<Integer , Integer > cnt , int x , int d ) {
156
+ if (cnt. merge(x, d, Integer :: sum) == 0 ) {
157
+ cnt. remove(x);
158
+ }
159
+ }
160
+
161
+ private boolean exist (Map<Integer , Integer > cnt , int x ) {
162
+ return cnt. getOrDefault(x, 0 ) > 0 ;
163
+ }
164
+
165
+ private long f (long i , long j ) {
166
+ return i * n + j;
167
+ }
168
+ }
169
+ ```
170
+
171
+ ### ** C++**
172
+
173
+ ``` cpp
174
+ class Solution {
175
+ public:
176
+ vector<int > gridIllumination(int n, vector<vector<int >>& lamps, vector<vector<int >>& queries) {
177
+ auto f = [ &] (int i, int j) -> long long {
178
+ return (long long) i * n + j;
179
+ };
180
+ unordered_set<long long > s;
181
+ unordered_map<int, int> row, col, diag1, diag2;
182
+ for (auto& lamp : lamps) {
183
+ int i = lamp[ 0] , j = lamp[ 1] ;
184
+ if (!s.count(f(i, j))) {
185
+ s.insert(f(i, j));
186
+ row[ i] ++;
187
+ col[ j] ++;
188
+ diag1[ i - j] ++;
189
+ diag2[ i + j] ++;
190
+ }
191
+ }
192
+ int m = queries.size();
193
+ vector<int > ans(m);
194
+ for (int k = 0; k < m; ++k) {
195
+ int i = queries[ k] [ 0 ] , j = queries[ k] [ 1 ] ;
196
+ if (row[ i] > 0 || col[ j] > 0 || diag1[ i - j] > 0 || diag2[ i + j] > 0) {
197
+ ans[ k] = 1;
198
+ }
199
+ for (int x = i - 1; x <= i + 1; ++x) {
200
+ for (int y = j - 1; y <= j + 1; ++y) {
201
+ if (x < 0 || x >= n || y < 0 || y >= n || !s.count(f(x, y))) {
202
+ continue;
173
203
}
204
+ s.erase(f(x, y));
205
+ row[ x] --;
206
+ col[ y] --;
207
+ diag1[ x - y] --;
208
+ diag2[ x + y] --;
174
209
}
175
210
}
176
211
}
177
212
return ans;
178
213
}
214
+ };
215
+ ```
216
+
217
+ ### **Go**
218
+
219
+ ```go
220
+ func gridIllumination(n int, lamps [][]int, queries [][]int) []int {
221
+ row, col, diag1, diag2 := map[int]int{}, map[int]int{}, map[int]int{}, map[int]int{}
222
+ type pair struct{ x, y int }
223
+ s := map[pair]bool{}
224
+ for _, lamp := range lamps {
225
+ i, j := lamp[0], lamp[1]
226
+ p := pair{i, j}
227
+ if !s[p] {
228
+ s[p] = true
229
+ row[i]++
230
+ col[j]++
231
+ diag1[i-j]++
232
+ diag2[i+j]++
233
+ }
234
+ }
235
+ m := len(queries)
236
+ ans := make([]int, m)
237
+ for k, q := range queries {
238
+ i, j := q[0], q[1]
239
+ if row[i] > 0 || col[j] > 0 || diag1[i-j] > 0 || diag2[i+j] > 0 {
240
+ ans[k] = 1
241
+ }
242
+ for x := i - 1; x <= i+1; x++ {
243
+ for y := j - 1; y <= j+1; y++ {
244
+ p := pair{x, y}
245
+ if s[p] {
246
+ s[p] = false
247
+ row[x]--
248
+ col[y]--
249
+ diag1[x-y]--
250
+ diag2[x+y]--
251
+ }
252
+ }
253
+ }
254
+ }
255
+ return ans
179
256
}
180
257
```
181
258
@@ -187,54 +264,44 @@ function gridIllumination(
187
264
lamps : number [][],
188
265
queries : number [][],
189
266
): number [] {
190
- let lights: Set <string > = new Set ();
191
- let rows: Map <number , number > = new Map (); // i
192
- let cols: Map <number , number > = new Map (); // j
193
- let mainDiagonal: Map <number , number > = new Map (); // i - j
194
- let subDiagonal: Map <number , number > = new Map (); // i + j
195
- for (let [i, j] of lamps ) {
196
- let key = ` ${i },${j } ` ;
197
- if (lights .has (key )) continue ;
198
- lights .add (key );
199
- rows .set (i , (rows .get (i ) || 0 ) + 1 );
200
- cols .set (j , (cols .get (j ) || 0 ) + 1 );
201
- mainDiagonal .set (i - j , (mainDiagonal .get (i - j ) || 0 ) + 1 );
202
- subDiagonal .set (i + j , (subDiagonal .get (i + j ) || 0 ) + 1 );
267
+ const row = new Map <number , number >();
268
+ const col = new Map <number , number >();
269
+ const diag1 = new Map <number , number >();
270
+ const diag2 = new Map <number , number >();
271
+ const s = new Set <number >();
272
+ for (const [i, j] of lamps ) {
273
+ if (s .has (i * n + j )) {
274
+ continue ;
275
+ }
276
+ s .add (i * n + j );
277
+ row .set (i , (row .get (i ) || 0 ) + 1 );
278
+ col .set (j , (col .get (j ) || 0 ) + 1 );
279
+ diag1 .set (i - j , (diag1 .get (i - j ) || 0 ) + 1 );
280
+ diag2 .set (i + j , (diag2 .get (i + j ) || 0 ) + 1 );
203
281
}
204
-
205
- let ans: Array <number > = [];
206
- let directions = [
207
- [- 1 , - 1 ],
208
- [- 1 , 0 ],
209
- [- 1 , 1 ],
210
- [0 , - 1 ],
211
- [0 , 0 ],
212
- [0 , 1 ],
213
- [1 , - 1 ],
214
- [1 , 0 ],
215
- [1 , 1 ],
216
- ];
217
- for (let [i, j] of queries ) {
218
- // check
219
- const check =
220
- lights .has (` ${i },${j } ` ) ||
221
- rows .get (i ) ||
222
- cols .get (j ) ||
223
- mainDiagonal .get (i - j ) ||
224
- subDiagonal .get (i + j );
225
- ans .push (check ? 1 : 0 );
226
- // close lamp
227
- for (let [dx, dy] of directions ) {
228
- const [x, y] = [i + dx , j + dy ];
229
- let key = ` ${x },${y } ` ;
230
- if (x < 0 || x > n - 1 || y < 0 || y > n - 1 || ! lights .has (key )) {
231
- continue ;
282
+ const ans: number [] = [];
283
+ for (const [i, j] of queries ) {
284
+ if (
285
+ row .get (i )! > 0 ||
286
+ col .get (j )! > 0 ||
287
+ diag1 .get (i - j )! > 0 ||
288
+ diag2 .get (i + j )! > 0
289
+ ) {
290
+ ans .push (1 );
291
+ } else {
292
+ ans .push (0 );
293
+ }
294
+ for (let x = i - 1 ; x <= i + 1 ; ++ x ) {
295
+ for (let y = j - 1 ; y <= j + 1 ; ++ y ) {
296
+ if (x < 0 || x >= n || y < 0 || y >= n || ! s .has (x * n + y )) {
297
+ continue ;
298
+ }
299
+ s .delete (x * n + y );
300
+ row .set (x , row .get (x )! - 1 );
301
+ col .set (y , col .get (y )! - 1 );
302
+ diag1 .set (x - y , diag1 .get (x - y )! - 1 );
303
+ diag2 .set (x + y , diag2 .get (x + y )! - 1 );
232
304
}
233
- lights .delete (key );
234
- rows .set (x , rows .get (x ) - 1 );
235
- cols .set (y , cols .get (y ) - 1 );
236
- mainDiagonal .set (x - y , mainDiagonal .get (x - y ) - 1 );
237
- subDiagonal .set (x + y , subDiagonal .get (x + y ) - 1 );
238
305
}
239
306
}
240
307
return ans ;
0 commit comments