Every day a Leetcode
题目来源:2768. 黑格子的数目
解法1:贡献法
坐标为 [x,y] 的黑块,位于左上角坐标为 [x-1,y-1]、[x-1,y]、[x,y-1]、[x,y] 的 2 x 2 的子矩阵内,对它们的黑色格子数的贡献都是 1。
遍历数组 coordinates,用一个哈希表 map<pair<int, int>, int> 统计左上角坐标为 [i,j] 的 2 x 2 的子矩阵内的黑块个数。
遍历哈希表,统计黑块数分别为 1、2、3、4 的子矩阵个数,它们的和为 sum。黑块数为 0 的子矩阵个数就是 (m-1)*(n-1)-sum。
答案是一个长度为 5 的数组,ans[i] 表示矩阵内黑块数为 i 的子矩阵个数。
代码:
/*
* @lc app=leetcode.cn id=2768 lang=cpp
*
* [2768] 黑格子的数目
*/
// @lc code=start
class Solution
{
private:
const int dx[4] = {-1, 0, -1, 0};
const int dy[4] = {-1, -1, 0, 0};
public:
vector<long long> countBlackBlocks(int m, int n, vector<vector<int>> &coordinates)
{
map<pair<int, int>, int> cnt;
for (vector<int> &coordinate : coordinates)
{
int x = coordinate[0], y = coordinate[1];
// 位于 [x,y] 的黑块,对 [x-1,y-1]、[x-1,y]、[x,y-1]、[x,y] 的贡献为 1
for (int k = 0; k < 4; k++)
{
int r = x + dx[k], c = y + dy[k];
if (r >= 0 && r < m - 1 && c >= 0 && c < n - 1)
cnt[{r, c}]++;
}
}
vector<long long> ans(5, 0LL);
for (auto &[p, c] : cnt)
ans[c]++;
ans[0] = (long long)(m - 1) * (n - 1) - accumulate(ans.begin() + 1, ans.end(), 0LL);
return ans;
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(p*k),其中 p 是数组 coordinates 的长度,k=4。
空间复杂度:O(m*n),其中 m 和 n 分别是网格的行数和列数。