返回介绍

solution / 0800-0899 / 0803.Bricks Falling When Hit / README_EN

发布于 2024-06-17 01:03:34 字数 10229 浏览 0 评论 0 收藏 0

803. Bricks Falling When Hit

中文文档

Description

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 the 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 that an erasure may refer to a location with no brick, and if it does, no bricks drop.

 

Example 1:

Input: grid = [[1,0,0,0],[1,1,1,0]], hits = [[1,0]]
Output: [2]
Explanation: Starting with the grid:
[[1,0,0,0],
 [1,1,1,0]]
We erase the underlined brick at (1,0), resulting in the grid:
[[1,0,0,0],
 [0,1,1,0]]
The two underlined bricks are no longer stable as they are no longer connected to the top nor adjacent to another stable brick, so they will fall. The resulting grid is:
[[1,0,0,0],
 [0,0,0,0]]
Hence the result is [2].

Example 2:

Input: grid = [[1,0,0,0],[1,1,0,0]], hits = [[1,1],[1,0]]
Output: [0,0]
Explanation: Starting with the grid:
[[1,0,0,0],
 [1,1,0,0]]
We erase the underlined brick at (1,1), resulting in the grid:
[[1,0,0,0],
 [1,0,0,0]]
All remaining bricks are still stable, so no bricks fall. The grid remains the same:
[[1,0,0,0],
 [1,0,0,0]]
Next, we erase the underlined brick at (1,0), resulting in the grid:
[[1,0,0,0],
 [0,0,0,0]]
Once again, all remaining bricks are still stable, so no bricks fall.
Hence the result is [0,0].

 

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 200
  • grid[i][j] is 0 or 1.
  • 1 <= hits.length <= 4 * 104
  • hits[i].length == 2
  • 0 <= x<= m - 1
  • 0 <= yi <= n - 1
  • All (xi, yi) are unique.

Solutions

Solution 1

class Solution:
  def hitBricks(self, grid: List[List[int]], hits: List[List[int]]) -> List[int]:
    def find(x):
      if p[x] != x:
        p[x] = find(p[x])
      return p[x]

    def union(a, b):
      pa, pb = find(a), find(b)
      if pa != pb:
        size[pb] += size[pa]
        p[pa] = pb

    m, n = len(grid), len(grid[0])
    p = list(range(m * n + 1))
    size = [1] * len(p)
    g = deepcopy(grid)
    for i, j in hits:
      g[i][j] = 0
    for j in range(n):
      if g[0][j] == 1:
        union(j, m * n)
    for i in range(1, m):
      for j in range(n):
        if g[i][j] == 0:
          continue
        if g[i - 1][j] == 1:
          union(i * n + j, (i - 1) * n + j)
        if j > 0 and g[i][j - 1] == 1:
          union(i * n + j, i * n + j - 1)
    ans = []
    for i, j in hits[::-1]:
      if grid[i][j] == 0:
        ans.append(0)
        continue
      g[i][j] = 1
      prev = size[find(m * n)]
      if i == 0:
        union(j, m * n)
      for a, b in [(-1, 0), (1, 0), (0, 1), (0, -1)]:
        x, y = i + a, j + b
        if 0 <= x < m and 0 <= y < n and g[x][y] == 1:
          union(i * n + j, x * n + y)
      curr = size[find(m * n)]
      ans.append(max(0, curr - prev - 1))
    return ans[::-1]
class Solution {
  private int[] p;
  private int[] size;

  public int[] hitBricks(int[][] grid, int[][] hits) {
    int m = grid.length;
    int n = grid[0].length;
    p = new int[m * n + 1];
    size = new int[m * n + 1];
    for (int i = 0; i < p.length; ++i) {
      p[i] = i;
      size[i] = 1;
    }
    int[][] g = new int[m][n];
    for (int i = 0; i < m; ++i) {
      for (int j = 0; j < n; ++j) {
        g[i][j] = grid[i][j];
      }
    }
    for (int[] h : hits) {
      g[h[0]][h[1]] = 0;
    }
    for (int j = 0; j < n; ++j) {
      if (g[0][j] == 1) {
        union(j, m * n);
      }
    }
    for (int i = 1; i < m; ++i) {
      for (int j = 0; j < n; ++j) {
        if (g[i][j] == 0) {
          continue;
        }
        if (g[i - 1][j] == 1) {
          union(i * n + j, (i - 1) * n + j);
        }
        if (j > 0 && g[i][j - 1] == 1) {
          union(i * n + j, i * n + j - 1);
        }
      }
    }
    int[] ans = new int[hits.length];
    int[] dirs = {-1, 0, 1, 0, -1};
    for (int k = hits.length - 1; k >= 0; --k) {
      int i = hits[k][0];
      int j = hits[k][1];
      if (grid[i][j] == 0) {
        continue;
      }
      g[i][j] = 1;
      int prev = size[find(m * n)];
      if (i == 0) {
        union(j, m * n);
      }
      for (int l = 0; l < 4; ++l) {
        int x = i + dirs[l];
        int y = j + dirs[l + 1];
        if (x >= 0 && x < m && y >= 0 && y < n && g[x][y] == 1) {
          union(i * n + j, x * n + y);
        }
      }
      int curr = size[find(m * n)];
      ans[k] = Math.max(0, curr - prev - 1);
    }
    return ans;
  }

  private int find(int x) {
    if (p[x] != x) {
      p[x] = find(p[x]);
    }
    return p[x];
  }

  private void union(int a, int b) {
    int pa = find(a);
    int pb = find(b);
    if (pa != pb) {
      size[pb] += size[pa];
      p[pa] = pb;
    }
  }
}
class Solution {
public:
  vector<int> p;
  vector<int> size;

  vector<int> hitBricks(vector<vector<int>>& grid, vector<vector<int>>& hits) {
    int m = grid.size(), n = grid[0].size();
    p.resize(m * n + 1);
    size.resize(m * n + 1);
    for (int i = 0; i < p.size(); ++i) {
      p[i] = i;
      size[i] = 1;
    }
    vector<vector<int>> g(m, vector<int>(n));
    for (int i = 0; i < m; ++i)
      for (int j = 0; j < n; ++j)
        g[i][j] = grid[i][j];
    for (auto& h : hits) g[h[0]][h[1]] = 0;
    for (int j = 0; j < n; ++j)
      if (g[0][j] == 1)
        merge(j, m * n);
    for (int i = 1; i < m; ++i) {
      for (int j = 0; j < n; ++j) {
        if (g[i][j] == 0) continue;
        if (g[i - 1][j] == 1) merge(i * n + j, (i - 1) * n + j);
        if (j > 0 && g[i][j - 1] == 1) merge(i * n + j, i * n + j - 1);
      }
    }
    vector<int> ans(hits.size());
    vector<int> dirs = {-1, 0, 1, 0, -1};
    for (int k = hits.size() - 1; k >= 0; --k) {
      int i = hits[k][0], j = hits[k][1];
      if (grid[i][j] == 0) continue;
      g[i][j] = 1;
      int prev = size[find(m * n)];
      if (i == 0) merge(j, m * n);
      for (int l = 0; l < 4; ++l) {
        int x = i + dirs[l], y = j + dirs[l + 1];
        if (x >= 0 && x < m && y >= 0 && y < n && g[x][y] == 1)
          merge(i * n + j, x * n + y);
      }
      int curr = size[find(m * n)];
      ans[k] = max(0, curr - prev - 1);
    }
    return ans;
  }

  int find(int x) {
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
  }

  void merge(int a, int b) {
    int pa = find(a), pb = find(b);
    if (pa != pb) {
      size[pb] += size[pa];
      p[pa] = pb;
    }
  }
};
func hitBricks(grid [][]int, hits [][]int) []int {
  m, n := len(grid), len(grid[0])
  p := make([]int, m*n+1)
  size := make([]int, len(p))
  for i := range p {
    p[i] = i
    size[i] = 1
  }

  var find func(x int) int
  find = func(x int) int {
    if p[x] != x {
      p[x] = find(p[x])
    }
    return p[x]
  }
  union := func(a, b int) {
    pa, pb := find(a), find(b)
    if pa != pb {
      size[pb] += size[pa]
      p[pa] = pb
    }
  }

  g := make([][]int, m)
  for i := range g {
    g[i] = make([]int, n)
    for j := range g[i] {
      g[i][j] = grid[i][j]
    }
  }
  for _, h := range hits {
    g[h[0]][h[1]] = 0
  }
  for j, v := range g[0] {
    if v == 1 {
      union(j, m*n)
    }
  }
  for i := 1; i < m; i++ {
    for j := 0; j < n; j++ {
      if g[i][j] == 0 {
        continue
      }
      if g[i-1][j] == 1 {
        union(i*n+j, (i-1)*n+j)
      }
      if j > 0 && g[i][j-1] == 1 {
        union(i*n+j, i*n+j-1)
      }
    }
  }
  ans := make([]int, len(hits))
  dirs := []int{-1, 0, 1, 0, -1}
  for k := len(hits) - 1; k >= 0; k-- {
    i, j := hits[k][0], hits[k][1]
    if grid[i][j] == 0 {
      continue
    }
    g[i][j] = 1
    prev := size[find(m*n)]
    if i == 0 {
      union(j, m*n)
    }
    for l := 0; l < 4; l++ {
      x, y := i+dirs[l], j+dirs[l+1]
      if x >= 0 && x < m && y >= 0 && y < n && g[x][y] == 1 {
        union(i*n+j, x*n+y)
      }
    }
    curr := size[find(m*n)]
    ans[k] = max(0, curr-prev-1)
  }
  return ans
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文