列表

详情


6928. 黑格子的数目

给你两个整数 m 和 n ,表示一个下标从 0 开始的 m x n 的网格图。

给你一个下标从 0 开始的二维整数矩阵 coordinates ,其中 coordinates[i] = [x, y] 表示坐标为 [x, y] 的格子是 黑色的 ,所有没出现在 coordinates 中的格子都是 白色的

一个块定义为网格图中 2 x 2 的一个子矩阵。更正式的,对于左上角格子为 [x, y] 的块,其中 0 <= x < m - 1 且 0 <= y < n - 1 ,包含坐标为 [x, y] ,[x + 1, y] ,[x, y + 1] 和 [x + 1, y + 1] 的格子。

请你返回一个下标从 0 开始长度为 5 的整数数组 arr ,arr[i] 表示恰好包含 i 个 黑色 格子的块的数目。

 

示例 1:

输入:m = 3, n = 3, coordinates = [[0,0]]
输出:[3,1,0,0,0]
解释:网格图如下:

只有 1 个块有一个黑色格子,这个块是左上角为 [0,0] 的块。
其他 3 个左上角分别为 [0,1] ,[1,0] 和 [1,1] 的块都有 0 个黑格子。
所以我们返回 [3,1,0,0,0] 。

示例 2:

输入:m = 3, n = 3, coordinates = [[0,0],[1,1],[0,2]]
输出:[0,2,2,0,0]
解释:网格图如下:

有 2 个块有 2 个黑色格子(左上角格子分别为 [0,0] 和 [0,1])。
左上角为 [1,0] 和 [1,1] 的两个块,都有 1 个黑格子。
所以我们返回 [0,2,2,0,0] 。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: vector<long long> countBlackBlocks(int m, int n, vector<vector<int>>& coordinates) { } };

javascript 解法, 执行用时: 596 ms, 内存消耗: 72.1 MB, 提交时间: 2023-07-10 09:55:11

/**
 * @param {number} m
 * @param {number} n
 * @param {number[][]} coordinates
 * @return {number[]}
 */
var countBlackBlocks = function (m, n, coordinates) {
  const map = new Map();
  const dir = [// 分别以当前坐标作为块左上角,左下角,右上角,右下角,计算出所有涉及到的块的坐标
    [0, 0],
    [0, -1],
    [-1, 0],
    [-1, -1],
  ];

  for (const [x, y] of coordinates) {
    for (const [dx, dy] of dir) {
      const nx = x + dx;
      const ny = y + dy;
      if (nx >= 0 && nx < m - 1 && ny >= 0 && ny < n - 1) {
        const key = `${nx}-${ny}`;
        map.set(key, (map.get(key) || 0) + 1);
      }
    }
  }

  const ans = new Array(5).fill(0);
  for (const [key, val] of map) {
    ans[val]++;
  }
  ans[0] = (m - 1) * (n - 1) - ans.reduce((a, b) => a + b, 0);

  return ans;
};

cpp 解法, 执行用时: 1020 ms, 内存消耗: 242.7 MB, 提交时间: 2023-07-10 09:53:23

/**
 * 哈希枚举
 * 枚举coordinates中的黑色格子, 每个黑色格子最多能使周围的4个块的块内黑格子数加1, 
 * 用哈希记录出现过的块的块内黑格子数.
 **/
class Solution {
public:
    vector<long long> countBlackBlocks(int m, int n, vector<vector<int>> &coordinates) {
        map<pair<int, int>, int> cnt;//块左上角的坐标 -> 块内黑格子数
        int dx[4] = {0, -1, -1, 0};
        int dy[4] = {-1, -1, 0, 0};
        for (auto &p: coordinates) {
            for (int k = 0; k < 4; k++) {
                int nx = p[0] + dx[k];
                int ny = p[1] + dy[k];
                if (nx < 0 || nx >= m - 1 || ny < 0 || ny >= n - 1)
                    continue;
                cnt[{nx, ny}]++;//块左上角的坐标为(nx,ny)的块的块内黑格子数更新
            }
        }
        vector<long long> res(5);
        for (auto &[_, v]: cnt)
            res[v]++;
        res[0] = 1LL * (m - 1) * (n - 1) - accumulate(res.begin() + 1, res.end(), 0);
        return res;
    }
};

golang 解法, 执行用时: 440 ms, 内存消耗: 9.6 MB, 提交时间: 2023-07-10 09:52:20

func countBlackBlocks(m, n int, coordinates [][]int) []int64 {
	type pair struct{ x, y int }
	set := make(map[pair]int, len(coordinates))
	for _, p := range coordinates {
		set[pair{p[0], p[1]}] = 1
	}

	arr := make([]int64, 5)
	vis := make(map[pair]bool, len(set)*4)
	for _, p := range coordinates {
		x, y := p[0], p[1]
		for i := max(x-1, 0); i <= x && i < m-1; i++ {
			for j := max(y-1, 0); j <= y && j < n-1; j++ {
				if !vis[pair{i, j}] {
					vis[pair{i, j}] = true
					cnt := set[pair{i, j}] + set[pair{i, j + 1}] +
						   set[pair{i + 1, j}] + set[pair{i + 1, j + 1}]
					arr[cnt]++
				}
			}
		}
	}
	arr[0] = int64(m-1)*int64(n-1) - int64(len(vis)) // 不含黑格子的块
	return arr
}

func max(a, b int) int { if b > a { return b }; return a }

python3 解法, 执行用时: 1276 ms, 内存消耗: 26.2 MB, 提交时间: 2023-07-10 09:51:45

'''
枚举
只考虑有黑格子的子矩阵,如果(x, y)处有黑格子, 则(x-1, y-1), (x-1, y), (x, y-1),(x,y)的块都包含这个黑格子。
代码实现时,注意不要重复统计,可以用哈希表 vis 来记录统计过的子矩阵左上角。
'''
class Solution:
    def countBlackBlocks(self, m: int, n: int, coordinates: List[List[int]]) -> List[int]:
        s = set(map(tuple, coordinates))
        arr = [0] * 5
        vis = set()
        for x, y in coordinates:
            for i in range(max(x - 1, 0), min(x + 1, m - 1)):
                for j in range(max(y - 1, 0), min(y + 1, n - 1)):
                    if (i, j) not in vis:
                        vis.add((i, j))
                        cnt = ((i, j) in s) + ((i, j + 1) in s) + \
                              ((i + 1, j) in s) + ((i + 1, j + 1) in s)
                        arr[cnt] += 1
        arr[0] = (m - 1) * (n - 1) - len(vis)
        return arr

上一题