classSolution: defpossibleToStamp(self, grid: List[List[int]], stampHeight: int, stampWidth: int) -> bool: m, n = len(grid), len(grid[0]) sum = [[0] * (n + 1) for _ inrange(m + 1)] diff = [[0] * (n + 1) for _ inrange(m + 1)] for i, row inenumerate(grid): for j, v inenumerate(row): # grid 的二维前缀和 sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + v
for i, row inenumerate(grid): for j, v inenumerate(row): if v == 0: x, y = i + stampHeight, j + stampWidth # 注意这是矩形右下角横纵坐标都 +1 后的位置 if x <= m and y <= n andsum[x][y] - sum[x][j] - sum[i][y] + sum[i][j] == 0: diff[i][j] += 1 diff[i][y] -= 1 diff[x][j] -= 1 diff[x][y] += 1# 更新二维差分
# 还原二维差分矩阵对应的计数矩阵,这里用滚动数组实现 cnt, pre = [0] * (n + 1), [0] * (n + 1) for i, row inenumerate(grid): for j, v inenumerate(row): cnt[j + 1] = cnt[j] + pre[j + 1] - pre[j] + diff[i][j] if cnt[j + 1] == 0and v == 0: returnFalse cnt, pre = pre, cnt returnTrue
classSolution { public: boolpossibleToStamp(vector<vector<int>> &grid, int stampHeight, int stampWidth){ int m = grid.size(), n = grid[0].size(); vector<vector<int>> sum(m + 1, vector<int>(n + 1)), diff(m + 1, vector<int>(n + 1)); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { // grid 的二维前缀和 sum[i + 1][j + 1] = sum[i + 1][j] + sum[i][j + 1] - sum[i][j] + grid[i][j]; } }
for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { int x = i + stampHeight, y = j + stampWidth; // 注意这是矩形右下角横纵坐标都 +1 后的位置 if (x <= m && y <= n && sum[x][y] - sum[x][j] - sum[i][y] + sum[i][j] == 0) { ++diff[i][j]; --diff[i][y]; --diff[x][j]; ++diff[x][y]; // 更新二维差分 } } }
funcpossibleToStamp(grid [][]int, stampHeight, stampWidth int)bool { m, n := len(grid), len(grid[0]) sum := make([][]int, m+1) sum[0] = make([]int, n+1) diff := make([][]int, m+1) diff[0] = make([]int, n+1) for i, row := range grid { sum[i+1] = make([]int, n+1) for j, v := range row { // grid 的二维前缀和 sum[i+1][j+1] = sum[i+1][j] + sum[i][j+1] - sum[i][j] + v } diff[i+1] = make([]int, n+1) }
for i, row := range grid { for j, v := range row { if v == 0 { x, y := i+stampHeight, j+stampWidth // 注意这是矩形右下角横纵坐标都 +1 后的位置 if x <= m && y <= n && sum[x][y]-sum[x][j]-sum[i][y]+sum[i][j] == 0 { diff[i][j]++ diff[i][y]-- diff[x][j]-- diff[x][y]++ // 更新二维差分 } } } }
// 还原二维差分矩阵对应的计数矩阵,这里用滚动数组实现 cnt := make([]int, n+1) pre := make([]int, n+1) for i, row := range grid { for j, v := range row { cnt[j+1] = cnt[j] + pre[j+1] - pre[j] + diff[i][j] if cnt[j+1] == 0 && v == 0 { returnfalse } } cnt, pre = pre, cnt } returntrue }