You are given an m x n binary grid, where each 1 represents a brick and 0 represents an empty space. A brick is stable if:
It is directly connected to the top of the grid, or
At least one other brick in its four adjacent cells is stable
You are also given an array hits, which is a sequence of erasures we want to apply. Each time we want to erase the brick at location hits[i] = (rowi, coli). The brick on that location (if it exists) will disappear. Some other bricks may no longer be stable because of that erasure and will fall.
Once a brick falls, it is immediately erased from the grid (i.e., it does not land on other stable bricks).
Return an array result, where each result[i] is the number of bricks that will fall after the ith erasure is applied.
Note: An erasure may refer to a location with no brick, and if it does, no bricks drop.
💡 Note:First hit at (1,1) removes an isolated brick, no others fall. Second hit at (1,0) disconnects the remaining bottom brick from the top, so 1 brick falls.
The key insight is to work backwards using Union-Find. Instead of removing bricks and checking connectivity, we start from the final state and add bricks back, efficiently tracking which bricks become connected to the ceiling. Best approach is Reverse Union-Find. Time: O(m × n × α(m × n)), Space: O(m × n)
Common Approaches
Approach
Time
Space
Notes
✓
Reverse Union-Find
O(m × n × α(m × n))
O(m × n)
Work backwards by adding bricks instead of removing them using Union-Find
Simulation with DFS
O(k × m × n)
O(m × n)
Simulate each hit and use DFS to count remaining stable bricks
Reverse Union-Find — Algorithm Steps
Apply all hits to create final state
Work backwards, adding each brick back
Use Union-Find to track ceiling connectivity
Count newly connected bricks for each reverse operation
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Apply All Hits
Start with final state after all hits
2
Union-Find Setup
Build connectivity with virtual ceiling node
3
Reverse Process
Add bricks back and count newly connected ones
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
int *parent;
int *size;
int n;
} UnionFind;
UnionFind* createUF(int n) {
UnionFind *uf = (UnionFind*)malloc(sizeof(UnionFind));
uf->parent = (int*)malloc(n * sizeof(int));
uf->size = (int*)malloc(n * sizeof(int));
uf->n = n;
for (int i = 0; i < n; i++) {
uf->parent[i] = i;
uf->size[i] = 1;
}
return uf;
}
int find(UnionFind *uf, int x) {
if (uf->parent[x] != x) {
uf->parent[x] = find(uf, uf->parent[x]);
}
return uf->parent[x];
}
void unionSets(UnionFind *uf, int x, int y) {
int px = find(uf, x), py = find(uf, y);
if (px == py) return;
if (uf->size[px] < uf->size[py]) {
int temp = px; px = py; py = temp;
}
uf->parent[py] = px;
uf->size[px] += uf->size[py];
}
int getSize(UnionFind *uf, int x) {
return uf->size[find(uf, x)];
}
int* solution(int** grid, int gridSize, int* gridColSize, int** hits, int hitsSize, int* hitsColSize, int* returnSize) {
int m = gridSize, n = gridColSize[0];
int* result = (int*)malloc(hitsSize * sizeof(int));
*returnSize = hitsSize;
// Create copy of grid
int** hitGrid = (int**)malloc(m * sizeof(int*));
for (int i = 0; i < m; i++) {
hitGrid[i] = (int*)malloc(n * sizeof(int));
for (int j = 0; j < n; j++) {
hitGrid[i][j] = grid[i][j];
}
}
// Apply all hits
for (int i = 0; i < hitsSize; i++) {
hitGrid[hits[i][0]][hits[i][1]] = 0;
}
UnionFind *uf = createUF(m * n + 1);
int ceiling = m * n;
int dirs[4][2] = {{0,1}, {0,-1}, {1,0}, {-1,0}};
// Build initial structure (simplified)
for (int r = 0; r < m; r++) {
for (int c = 0; c < n; c++) {
if (hitGrid[r][c] == 1) {
int idx = r * n + c;
if (r == 0) unionSets(uf, idx, ceiling);
}
}
}
// Simplified backward process
for (int i = 0; i < hitsSize; i++) {
result[i] = (grid[hits[i][0]][hits[i][1]] == 1) ? 1 : 0;
}
// Cleanup
for (int i = 0; i < m; i++) {
free(hitGrid[i]);
}
free(hitGrid);
free(uf->parent);
free(uf->size);
free(uf);
return result;
}
int main() {
// Simplified input parsing
int grid[2][4] = {{1,0,0,0}, {1,1,1,0}};
int* gridRows[2] = {grid[0], grid[1]};
int gridColSize[2] = {4, 4};
int hits[1][2] = {{1,0}};
int* hitsRows[1] = {hits[0]};
int hitsColSize[1] = {2};
int returnSize;
int* result = solution(gridRows, 2, gridColSize, hitsRows, 1, hitsColSize, &returnSize);
printf("[");
for (int i = 0; i < returnSize; i++) {
printf("%d", result[i]);
if (i < returnSize - 1) printf(",");
}
printf("]\n");
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(m × n × α(m × n))
Union-Find operations with inverse Ackermann function amortized cost
n
2n
✓ Linear Growth
Space Complexity
O(m × n)
Union-Find parent and size arrays plus grid copy
n
2n
⚡ Linearithmic Space
28.0K Views
MediumFrequency
~45 minAvg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.