You are given an m x n binary matrix grid where each cell is either 0 (empty) or 1 (occupied).
You are then given stamps of size stampHeight x stampWidth. We want to fit the stamps such that they follow the given restrictions and requirements:
Cover all the empty cells.
Do not cover any of the occupied cells.
We can put as many stamps as we want.
Stamps can overlap with each other.
Stamps are not allowed to be rotated.
Stamps must stay completely inside the grid.
Return trueif it is possible to fit the stamps while following the given restrictions and requirements. Otherwise, returnfalse.
Example 1:
Input: grid = [[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0],[1,0,0,0]], stampHeight = 4, stampWidth = 3
Output: true
Explanation: We have two overlapping stamps (labeled 1 and 2 in the image) that are able to cover all the empty cells.
Example 2:
Input: grid = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]], stampHeight = 2, stampWidth = 2
Output: false
Explanation: There is no way to fit the stamps onto all the empty cells without the stamps going outside the grid.
Constraints:
m == grid.length
n == grid[r].length
1 <= m, n <= 105
1 <= m * n <= 2 * 105
grid[r][c] is either 0 or 1.
1 <= stampHeight, stampWidth <= 105
Solutions
Solution 1: Two-Dimensional Prefix Sum + Two-Dimensional Difference
According to the problem description, every empty cell must be covered by a stamp, and no occupied cell can be covered. Therefore, we can traverse the two-dimensional matrix, and for each cell, if all cells in the area of $stampHeight \times stampWidth$ with this cell as the upper left corner are empty (i.e., not occupied), then we can place a stamp at this cell.
To quickly determine whether all cells in an area are empty, we can use a two-dimensional prefix sum. We use $s_{i,j}$ to represent the number of occupied cells in the sub-matrix from $(1,1)$ to $(i,j)$ in the two-dimensional matrix. That is, $s_{i, j} = s_{i - 1, j} + s_{i, j - 1} - s_{i - 1, j - 1} + grid_{i-1, j-1}$.
Then, with $(i, j)$ as the upper left corner, and the height and width are $stampHeight$ and $stampWidth$ respectively, the lower right coordinate of the sub-matrix is $(x, y) = (i + stampHeight - 1, j + stampWidth - 1)$. We can calculate the number of occupied cells in this sub-matrix through $s_{x, y} - s_{x, j - 1} - s_{i - 1, y} + s_{i - 1, j - 1}$. If the number of occupied cells in this sub-matrix is $0$, then we can place a stamp at $(i, j)$. After placing the stamp, all cells in this $stampHeight \times stampWidth$ area will become occupied cells. We can use a two-dimensional difference array $d$ to record this change. That is:
Finally, we perform a prefix sum operation on the two-dimensional difference array $d$ to find out the number of times each cell is covered by a stamp. If a cell is not occupied and the number of times it is covered by a stamp is $0$, then we cannot place a stamp at this cell, so we need to return $\texttt{false}$. If all "unoccupied cells" are successfully covered by stamps, return $\texttt{true}$.
The time complexity is $O(m \times n)$, and the space complexity is $O(m \times n)$. Here, $m$ and $n$ are the height and width of the two-dimensional matrix, respectively.
implSolution{pubfnpossible_to_stamp(grid:Vec<Vec<i32>>,stamp_height:i32,stamp_width:i32)->bool{letn:usize=grid.len();letm:usize=grid[0].len();letmutprefix_vec:Vec<Vec<i32>>=vec![vec![0;m+1];n+1];// Initialize the prefix vectorforiin0..n{forjin0..m{prefix_vec[i+1][j+1]=prefix_vec[i][j+1]+prefix_vec[i+1][j]-prefix_vec[i][j]+grid[i][j];}}letmutdiff_vec:Vec<Vec<i32>>=vec![vec![0;m+1];n+1];// Construct the difference vector based on prefix sum vectorforiin0..n{forjin0..m{// If the value of the cell is one, just bypass thisifgrid[i][j]==1{continue;}// Otherwise, try stick the stampletx:usize=i+(stamp_heightasusize);lety:usize=j+(stamp_widthasusize);// Check the boundifx<=n&&y<=m{// If the region can be sticked (All cells are empty, which means the sum will be zero)ifprefix_vec[x][y]-prefix_vec[x][j]-prefix_vec[i][y]+prefix_vec[i][j]==0{// Update the difference vectordiff_vec[i][j]+=1;diff_vec[x][y]+=1;diff_vec[x][j]-=1;diff_vec[i][y]-=1;}}}}letmutcheck_vec:Vec<Vec<i32>>=vec![vec![0;m+1];n+1];// Check the prefix sum of difference vector, to determine if there is any empty cell leftforiin0..n{forjin0..m{// If the value of the cell is one, just bypass thisifgrid[i][j]==1{continue;}// Otherwise, check if the region is empty, by calculating the prefix sum of difference vectorcheck_vec[i+1][j+1]=check_vec[i][j+1]+check_vec[i+1][j]-check_vec[i][j]+diff_vec[i][j];ifcheck_vec[i+1][j+1]==0{returnfalse;}}}true}}