803. 打砖块
Desp:
有一个m x n
的二元网格grid
,其中1
表示砖块,0
表示空白。砖块 稳定(不会掉落)的前提是: 一块砖直接连接到网格的顶部,或者 至少有一块相邻(4 个方向之一)砖块 稳定 不会掉落时 给你一个数组hits
,这是需要依次消除砖块的位置。每当消除hits[i] = (rowi, coli)
位置上的砖块时,对应位置的砖块(若存在)会消失,然后其他的砖块可能因为这一消除操作而 掉落 。一旦砖块掉落,它会 立即 从网格grid
中消失(即,它不会落在其他稳定的砖块上)。 返回一个数组result
,其中result[i]
表示第i
次消除操作对应掉落的砖块数目。
注意,消除可能指向是没有砖块的空白位置,如果发生这种情况,则没有砖块掉落。
class Solution {
public int[] hitBricks(int[][] grid, int[][] hits) {
int n = hits.length;
int[] ans = new int[n];
for(int[] h : hits) {
int r = h[0];
int c = h[1];
if(grid[r][c] == 1) {
grid[r][c] = 2;
}
}
UnionFind uf = new UnionFind(grid);
for(int i = n - 1; i >= 0; i--) {
int r = hits[i][0];
int c = hits[i][1];
if(grid[r][c] == 2) {
ans[i] = uf.manager(r, c);
}
}
return ans;
}
}
class UnionFind {
int[][] grid;//修改过的数组
int n;
int m;
int cellingAll;//连在天花板砖块的数量
Dot[][] dots;//点
HashSet<Dot> cellingSet;//天花板的点
HashMap<Dot, Dot> fatherMap;
HashMap<Dot, Integer> sizeMap;
public UnionFind(int[][] matrix) {
inti(matrix);
connect();
}
public int manager(int i, int j) {
grid[i][j] = 1;
Dot cur = new Dot();
dots[i][j] = cur;
if(i == 0) {
cellingAll++;
cellingSet.add(cur);
}
fatherMap.put(cur, cur);
sizeMap.put(cur, 1);
int pre = cellingAll;
union(i, j, i - 1, j);
union(i, j, i + 1, j);
union(i, j, i, j - 1);
union(i, j, i, j + 1);
int now = cellingAll;
if(i == 0) {
return now - pre;
}
return now == pre ? 0 : now - pre - 1;
}
private void union(int r1, int c1, int r2, int c2) {
if(valid(r1, c1) && valid(r2, c2)) {
Dot f1 = find(r1, c1);
Dot f2 = find(r2, c2);
if(f1 != f2) {
int size1 = sizeMap.get(f1);
int size2 = sizeMap.get(f2);
boolean statu1 = cellingSet.contains(f1);
boolean statu2 = cellingSet.contains(f2);
if(size1 < size2) {
fatherMap.put(f1, f2);
sizeMap.put(f2, size1 + size2);
if(statu1 ^ statu2) {
cellingSet.add(f2);
cellingAll += statu1 ? size2 : size1;
}
} else {
fatherMap.put(f2, f1);
sizeMap.put(f1, size1 + size2);
if(statu1 ^ statu2) {
cellingSet.add(f1);
cellingAll += statu1 ? size2 : size1;
}
}
}
}
}
private Dot find(int r, int c) {
Dot dot = dots[r][c];
Stack<Dot> stack = new Stack<>();
while(dot != fatherMap.get(dot)) {
stack.push(dot);
dot = fatherMap.get(dot);
}
while(!stack.isEmpty()) {
fatherMap.put(stack.pop(), dot);
}
return dot;
}
private boolean valid(int i, int j) {
return i < n && i >= 0 && j < m && j >= 0 && grid[i][j] == 1;
}
private void connect() {
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++ ) {
union(i, j, i - 1, j);
union(i, j, i + 1, j);
union(i, j, i, j - 1);
union(i, j, i, j + 1);
}
}
}
private void inti(int[][] matrix) {
grid = matrix;
n = matrix.length;
m = matrix[0].length;
cellingAll = 0;
cellingSet = new HashSet<>();
fatherMap = new HashMap<>();
sizeMap = new HashMap<>();
dots = new Dot[n][m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++ ){
if(grid[i][j] == 1) {
Dot cur = new Dot();
dots[i][j] = cur;
fatherMap.put(cur, cur);
sizeMap.put(cur, 1);
if(i == 0) {
cellingAll++;
cellingSet.add(cur);
}
}
}
}
}
}
class Dot {}
本文由 mdnice 多平台发布