Skip to content

Commit 5cc3709

Browse files
committed
feat: add solutions to lc problem: No.1001
No.1001.Grid Illumination
1 parent 3a8df53 commit 5cc3709

File tree

8 files changed

+558
-375
lines changed

8 files changed

+558
-375
lines changed

solution/1000-1099/1000.Minimum Cost to Merge Stones/README.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@
6060

6161
**方法一:动态规划(区间 DP)+ 前缀和**
6262

63-
不妨记题目中的 $k$ 为 $K$, $n$ 为石头的堆数
63+
我们不妨记题目中的 $k$ 为 $K$,石头的堆数为 $n$。
6464

65-
我们定义 $f[i][j][k]$ 表示将区间 $[i, j]$ 中的石头合并成 $k$ 堆的最小成本。初始时 $f[i][i][1] = 0$,其他位置的值均为 $\infty$。
65+
定义 $f[i][j][k]$ 表示将区间 $[i, j]$ 中的石头合并成 $k$ 堆的最小成本。初始时 $f[i][i][1] = 0$,其他位置的值均为 $\infty$。
6666

6767
注意到 $k$ 的取值范围为 $[1, K]$,因此我们需要枚举 $k$ 的值。
6868

@@ -76,7 +76,7 @@ $$
7676

7777
最后答案即为 $f[1][n][1]$,其中 $n$ 为石头的堆数。
7878

79-
时间复杂度 $O(n^3)$,空间复杂度 $O(n^3)$。其中 $n$ 为石头的堆数。
79+
时间复杂度 $O(n^3 \times k)$,空间复杂度 $O(n^2 \times k)$。其中 $n$ 为石头的堆数。
8080

8181
<!-- tabs:start -->
8282

solution/1000-1099/1001.Grid Illumination/README.md

+194-127
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,19 @@
6161

6262
<!-- 这里可写通用的实现逻辑 -->
6363

64-
哈希表
64+
**方法一:哈希表**
6565

66-
假设一盏灯的坐标为 `(x, y)`,那么它所在的行的数值为 x,列的数值为 y,正对角线的数值为 x-y,反对角线的数值为 x+y。确定某一直线的唯一数值标识后,我们就可以通过哈希表来记录某一直线所拥有的灯的数目。
66+
假设一盏灯的坐标为 $(x, y)$,那么它所在的行的数值为 $x$,列的数值为 $y$,正对角线的数值为 $x-y$,反对角线的数值为 $x+y$。确定某一直线的唯一数值标识后,我们就可以通过哈希表来记录某一直线所拥有的灯的数目。
6767

68-
遍历 lamps,将当前遍历到的灯所在的行、列和正、反对角线拥有灯的数目分别加 1
68+
我们遍历数组 $lamps$,将当前遍历到的灯所在的行、列和正、反对角线拥有灯的数目分别加 $1$
6969

70-
在处理 lamps 时,需要进行去重,因为我们将重复的灯看作同一盏灯。
70+
注意,在处理 $lamps$ 时,需要进行去重,因为我们将重复的灯看作同一盏灯。
7171

72-
遍历 queries,判断当前查询点所在的行,列和正、反对角线是否有灯,如果有,则置 1,即该点在查询时是被照亮的。然后进行关闭操作,查找查询点所在的八近邻点及它本身是否有灯,如果有,将该点所在的行、列和正、反对角线的灯数目分别减 1,并且将灯从网格中去掉。
72+
接下来,我们遍历 queries,判断当前查询点所在的行,列和正、反对角线是否有灯,如果有,则置 $1$,即该点在查询时是被照亮的。然后进行关闭操作,查找查询点所在的八近邻点及它本身是否有灯,如果有,将该点所在的行、列和正、反对角线的灯数目分别减 $1$,并且将灯从网格中去掉。
73+
74+
最后,返回答案数组即可。
75+
76+
时间复杂度 $O(m + q)$,其中 $m$ 和 $q$ 分别为数组 $lamps$ 和 $queries$ 的长度。
7377

7478
<!-- tabs:start -->
7579

@@ -79,41 +83,26 @@
7983

8084
```python
8185
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
9494
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
117106
return ans
118107
```
119108

@@ -123,59 +112,147 @@ class Solution:
123112

124113
```java
125114
class Solution {
115+
private int n;
126116
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);
141130
}
142131
}
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))) {
155142
continue;
156143
}
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;
173203
}
204+
s.erase(f(x, y));
205+
row[x]--;
206+
col[y]--;
207+
diag1[x - y]--;
208+
diag2[x + y]--;
174209
}
175210
}
176211
}
177212
return ans;
178213
}
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
179256
}
180257
```
181258

@@ -187,54 +264,44 @@ function gridIllumination(
187264
lamps: number[][],
188265
queries: number[][],
189266
): 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);
203281
}
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);
232304
}
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);
238305
}
239306
}
240307
return ans;

0 commit comments

Comments
 (0)