Skip to content

Commit b2942b4

Browse files
committed
feat: add solutions to lc problem: No.0803.Bricks Falling When Hit
1 parent dafb02c commit b2942b4

File tree

6 files changed

+907
-3
lines changed

6 files changed

+907
-3
lines changed

solution/0800-0899/0803.Bricks Falling When Hit/README.md

+307-2
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@
7676
<li>所有 <code>(x<sub>i</sub>, y<sub>i</sub>)</code> 互不相同</li>
7777
</ul>
7878

79-
8079
## 解法
8180

81+
逆向并查集,此过程中用 size 数组维护每个连通分量的大小。
82+
8283
<!-- 这里可写通用的实现逻辑 -->
8384

8485
<!-- tabs:start -->
@@ -88,15 +89,319 @@
8889
<!-- 这里可写当前语言的特殊实现逻辑 -->
8990

9091
```python
91-
92+
class Solution:
93+
def hitBricks(self, grid: List[List[int]], hits: List[List[int]]) -> List[int]:
94+
m, n = len(grid), len(grid[0])
95+
p = list(range(m * n + 1))
96+
size = [1] * len(p)
97+
g = [[grid[i][j] for j in range(n)] for i in range(m)]
98+
99+
def find(x):
100+
if p[x] != x:
101+
p[x] = find(p[x])
102+
return p[x]
103+
104+
def union(a, b):
105+
pa, pb = find(a), find(b)
106+
if pa != pb:
107+
size[pb] += size[pa]
108+
p[pa] = pb
109+
110+
def check(i, j):
111+
return 0 <= i < m and 0 <= j < n and g[i][j] == 1
112+
113+
for i, j in hits:
114+
g[i][j] = 0
115+
116+
for j in range(n):
117+
if g[0][j] == 1:
118+
union(j, m * n)
119+
120+
for i in range(1, m):
121+
for j in range(n):
122+
if g[i][j] == 0:
123+
continue
124+
if g[i - 1][j] == 1:
125+
union(i * n + j, (i - 1) * n + j)
126+
if j > 0 and g[i][j - 1] == 1:
127+
union(i * n + j, i * n + j - 1)
128+
129+
res = []
130+
for i, j in hits[::-1]:
131+
if grid[i][j] == 0:
132+
res.append(0)
133+
continue
134+
origin = size[find(m * n)]
135+
if i == 0:
136+
union(j, m * n)
137+
for x, y in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
138+
if check(i + x, j + y):
139+
union(i * n + j, (i + x) * n + (j + y))
140+
cur = size[find(m * n)]
141+
res.append(max(0, cur - origin - 1))
142+
g[i][j] = 1
143+
return res[::-1]
92144
```
93145

94146
### **Java**
95147

96148
<!-- 这里可写当前语言的特殊实现逻辑 -->
97149

98150
```java
151+
class Solution {
152+
private int[] p;
153+
private int[] size;
154+
private int[][] g;
155+
private int m;
156+
private int n;
157+
private int[][] dirs = new int[][]{{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
158+
159+
public int[] hitBricks(int[][] grid, int[][] hits) {
160+
m = grid.length;
161+
n = grid[0].length;
162+
p = new int[m * n + 1];
163+
size = new int[m * n + 1];
164+
for (int i = 0; i < p.length; ++i) {
165+
p[i] = i;
166+
size[i] = 1;
167+
}
168+
g = new int[m][n];
169+
for (int i = 0; i < m; ++i) {
170+
for (int j = 0; j < n; ++j) {
171+
g[i][j] = grid[i][j];
172+
}
173+
}
174+
for (int[] e : hits) {
175+
g[e[0]][e[1]] = 0;
176+
}
177+
for (int j = 0; j < n; ++j) {
178+
if (g[0][j] == 1) {
179+
union(j, m * n);
180+
}
181+
}
182+
for (int i = 1; i < m; ++i) {
183+
for (int j = 0; j < n; ++j) {
184+
if (g[i][j] == 0) {
185+
continue;
186+
}
187+
if (g[i - 1][j] == 1) {
188+
union(i * n + j, (i - 1) * n + j);
189+
}
190+
if (j > 0 && g[i][j - 1] == 1) {
191+
union(i * n + j, i * n + j - 1);
192+
}
193+
}
194+
}
195+
int[] res = new int[hits.length];
196+
for (int k = hits.length - 1; k >= 0; --k) {
197+
int i = hits[k][0], j = hits[k][1];
198+
if (grid[i][j] == 0) {
199+
continue;
200+
}
201+
int origin = size[find(m * n)];
202+
if (i == 0) {
203+
union(j, m * n);
204+
}
205+
for (int[] e : dirs) {
206+
if (check(i + e[0], j + e[1])) {
207+
union(i * n + j, (i + e[0]) * n + j + e[1]);
208+
}
209+
}
210+
int cur = size[find(m * n)];
211+
res[k] = Math.max(0, cur - origin - 1);
212+
g[i][j] = 1;
213+
}
214+
return res;
215+
}
216+
217+
private int find(int x) {
218+
if (p[x] != x) {
219+
p[x] = find(p[x]);
220+
}
221+
return p[x];
222+
}
223+
224+
private void union(int a, int b) {
225+
int pa = find(a), pb = find(b);
226+
if (pa != pb) {
227+
size[pb] += size[pa];
228+
p[pa] = pb;
229+
}
230+
}
231+
232+
private boolean check(int i, int j) {
233+
return i >= 0 && i < m && j >= 0 && j < n && g[i][j] == 1;
234+
}
235+
}
236+
```
237+
238+
### **C++**
239+
240+
```cpp
241+
class Solution {
242+
public:
243+
vector<int> p;
244+
vector<int> size;
245+
vector<vector<int>> g;
246+
int m;
247+
int n;
248+
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
249+
250+
vector<int> hitBricks(vector<vector<int>>& grid, vector<vector<int>>& hits) {
251+
m = grid.size();
252+
n = grid[0].size();
253+
for (int i = 0; i < m * n + 1; ++i)
254+
{
255+
p.push_back(i);
256+
size.push_back(1);
257+
}
258+
g = grid;
259+
for (auto e : hits)
260+
g[e[0]][e[1]] = 0;
261+
for (int j = 0; j < n; ++j)
262+
if (g[0][j] == 1)
263+
merge(j, m * n);
264+
for (int i = 1; i < m; ++i)
265+
{
266+
for (int j = 0; j < n; ++j)
267+
{
268+
if (g[i][j] == 0) continue;
269+
if (g[i - 1][j] == 1) merge(i * n + j, (i - 1) * n + j);
270+
if (j > 0 && g[i][j - 1] == 1) merge(i * n + j, i * n + j - 1);
271+
}
272+
}
273+
vector<int> res(hits.size());
274+
for (int k = hits.size() - 1; k >= 0; --k)
275+
{
276+
int i = hits[k][0], j = hits[k][1];
277+
if (grid[i][j] == 0) continue;
278+
int origin = size[find(m * n)];
279+
if (i == 0)
280+
merge(j, m * n);
281+
for (auto dir : dirs)
282+
if (check(i + dir[0], j + dir[1]))
283+
merge(i * n + j, ((i + dir[0]) * n + j + dir[1]));
284+
int cur = size[find(m * n)];
285+
res[k] = max(0, cur - origin - 1);
286+
g[i][j] = 1;
287+
}
288+
return res;
289+
}
290+
291+
int find(int x) {
292+
if (p[x] != x) p[x] = find(p[x]);
293+
return p[x];
294+
}
295+
296+
void merge(int a, int b) {
297+
int pa = find(a), pb = find(b);
298+
if (pa != pb)
299+
{
300+
size[pb] += size[pa];
301+
p[pa] = pb;
302+
}
303+
}
304+
305+
bool check(int i, int j) {
306+
return i >= 0 && i < m && j >= 0 && j < n && g[i][j] == 1;
307+
}
308+
};
309+
```
99310
311+
### **Go**
312+
313+
```go
314+
var p []int
315+
var size []int
316+
var g [][]int
317+
var m int
318+
var n int
319+
320+
func hitBricks(grid [][]int, hits [][]int) []int {
321+
m, n = len(grid), len(grid[0])
322+
p = make([]int, m*n+1)
323+
size = make([]int, m*n+1)
324+
for i := 0; i < len(p); i++ {
325+
p[i] = i
326+
size[i] = 1
327+
}
328+
g = make([][]int, m)
329+
for i := 0; i < m; i++ {
330+
g[i] = make([]int, n)
331+
for j := 0; j < n; j++ {
332+
g[i][j] = grid[i][j]
333+
}
334+
}
335+
for _, e := range hits {
336+
g[e[0]][e[1]] = 0
337+
}
338+
for j := 0; j < n; j++ {
339+
if g[0][j] == 1 {
340+
union(j, m*n)
341+
}
342+
}
343+
for i := 1; i < m; i++ {
344+
for j := 0; j < n; j++ {
345+
if g[i][j] == 0 {
346+
continue
347+
}
348+
if g[i-1][j] == 1 {
349+
union(i*n+j, (i-1)*n+j)
350+
}
351+
if j > 0 && g[i][j-1] == 1 {
352+
union(i*n+j, i*n+j-1)
353+
}
354+
}
355+
}
356+
357+
res := make([]int, len(hits))
358+
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
359+
for k := len(hits) - 1; k >= 0; k-- {
360+
i, j := hits[k][0], hits[k][1]
361+
if grid[i][j] == 0 {
362+
continue
363+
}
364+
origin := size[find(m*n)]
365+
if i == 0 {
366+
union(j, m*n)
367+
}
368+
for _, dir := range dirs {
369+
if check(i+dir[0], j+dir[1]) {
370+
union(i*n+j, (i+dir[0])*n+j+dir[1])
371+
}
372+
}
373+
cur := size[find(m*n)]
374+
res[k] = max(0, cur-origin-1)
375+
g[i][j] = 1
376+
}
377+
return res
378+
}
379+
380+
func find(x int) int {
381+
if p[x] != x {
382+
p[x] = find(p[x])
383+
}
384+
return p[x]
385+
}
386+
387+
func union(a, b int) {
388+
pa, pb := find(a), find(b)
389+
if pa != pb {
390+
size[pb] += size[pa]
391+
p[pa] = pb
392+
}
393+
}
394+
395+
func check(i, j int) bool {
396+
return i >= 0 && i < m && j >= 0 && j < n && g[i][j] == 1
397+
}
398+
399+
func max(a, b int) int {
400+
if a > b {
401+
return a
402+
}
403+
return b
404+
}
100405
```
101406

102407
### **...**

0 commit comments

Comments
 (0)