Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 207d9d3

Browse files
committed
feat: add solutions to lc problem: No.2132
No.2132.Stamping the Grid
1 parent 9818d4b commit 207d9d3

File tree

8 files changed

+495
-409
lines changed

8 files changed

+495
-409
lines changed

‎solution/2100-2199/2132.Stamping the Grid/README.md‎

Lines changed: 165 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -60,21 +60,24 @@
6060

6161
**方法一:二维前缀和 + 二维差分**
6262

63-
根据题给的约束,很容易推出,一个格子能贴邮票的条件为,在加上邮票的长和宽后,右下角不越界的情况下,当前子区域中所有格子的和为 0
63+
根据题目描述,每一个空格子都必须被邮票覆盖,而且不能覆盖任何被占据的格子。因此,我们可以遍历二维矩阵,对于每个格子,如果以该格子为左上角的 $stampHeight \times stampWidth$ 的区域内的所有格子都是空格子(即没有被占据),那么我们就可以在该格子处放置一个邮票
6464

65-
那么显然我们可以维护一个二维的前缀和数组,在 `O(1)` 的时间复杂度下就可以判断每次遍历到的格子是否能贴邮票
65+
为了快速判断一个区域内的所有格子是否都是空格子,我们可以使用二维前缀和。我们用 $s_{i,j}$ 表示二维矩阵中从 $(1,1)$ 到 $(i,j)$ 的子矩阵中被占据的格子的数量。即 $s_{i, j} = s_{i - 1, j} + s_{i, j - 1} - s_{i - 1, j - 1} + grid_{i-1, j-1}$
6666

67-
而因为贴邮票的操作,可以概括为将当前子区域的所有格子的值都置为 `1`,很自然的就能想到用一个二维的差分数组来维护贴邮票后的状态。
67+
那么以 $(i, j)$ 为左上角,且高度和宽度分别为 $stampHeight$ 和 $stampWidth$ 的子矩阵的右下角坐标为 $(x, y) = (i + stampHeight - 1, j + stampWidth - 1),ドル我们可以通过 $s_{x, y} - s_{x, j - 1} - s_{i - 1, y} + s_{i - 1, j - 1}$ 来计算出该子矩阵中被占据的格子的数量。如果该子矩阵中被占据的格子的数量为 0ドル,ドル那么我们就可以在 $(i, j)$ 处放置一个邮票,放置邮票后,这 $stampHeight \times stampWidth$ 的区域内的所有格子都会变成被占据的格子,我们可以用二维差分数组 $d$ 来记录这一变化。即:
6868

69-
最后只要对该差分数组再求一次二维前缀和,只要当前格子的和为 `0`,就意味着存在没有覆盖完全的情况,直接返回 `false` 即可。
69+
$$
70+
\begin{aligned}
71+
d_{i, j} &\leftarrow d_{i, j} + 1 \\
72+
d_{i, y + 1} &\leftarrow d_{i, y + 1} - 1 \\
73+
d_{x + 1, j} &\leftarrow d_{x + 1, j} - 1 \\
74+
d_{x + 1, y + 1} &\leftarrow d_{x + 1, y + 1} + 1
75+
\end{aligned}
76+
$$
7077

71-
需要注意的是二维数组的下标关系,具体参考如下
78+
最后,我们对二维差分数组 $d$ 进行前缀和运算,可以得出每个格子被邮票覆盖的次数。如果某个格子没有被占据,且被邮票覆盖的次数为 0ドル,ドル那么我们就无法将邮票放置在该格子处,因此我们需要返回 $\texttt{false}$。如果所有"没被占据的格子"都成功被邮票覆盖,返回 $\texttt{true}$
7279

73-
`s[i + 1][j + 1]` 表示第 i 行第 j 列左上部分所有元素之和,其中 i, j 下标从 0 开始。
74-
75-
`s[i + 1][j + 1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + nums[i][j]`
76-
77-
以 (x1, y1) 为左上角,(x2, y2) 为右下角的子矩阵和 `sub = s[x2 + 1][y2 + 1] - s[x2 + 1][y1] - s[x1][y2 + 1] + s[x1][y1]`
80+
时间复杂度 $O(m \times n),ドル空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是二维矩阵的高度和宽度。
7881

7982
<!-- tabs:start -->
8083

@@ -89,26 +92,22 @@ class Solution:
8992
) -> bool:
9093
m, n = len(grid), len(grid[0])
9194
s = [[0] * (n + 1) for _ in range(m + 1)]
92-
for i, row in enumerate(grid):
93-
for j, v in enumerate(row):
94-
s[i + 1][j + 1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + v
95-
96-
d = [[0] * (n + 1) for _ in range(m + 1)]
97-
for i, row in enumerate(grid):
98-
for j, v in enumerate(row):
99-
if v == 0:
100-
x, y = i + stampHeight, j + stampWidth
101-
if x <= m and y <= n and s[x][y] - s[x][j] - s[i][y] + s[i][j] == 0:
102-
d[i][j] += 1
103-
d[i][y] -= 1
104-
d[x][j] -= 1
105-
d[x][y] += 1
106-
107-
cnt = [[0] * (n + 1) for _ in range(m + 1)]
108-
for i, row in enumerate(grid):
109-
for j, v in enumerate(row):
110-
cnt[i + 1][j + 1] = cnt[i + 1][j] + cnt[i][j + 1] - cnt[i][j] + d[i][j]
111-
if v == 0 and cnt[i + 1][j + 1] == 0:
95+
for i, row in enumerate(grid, 1):
96+
for j, v in enumerate(row, 1):
97+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + v
98+
d = [[0] * (n + 2) for _ in range(m + 2)]
99+
for i in range(1, m - stampHeight + 2):
100+
for j in range(1, n - stampWidth + 2):
101+
x, y = i + stampHeight - 1, j + stampWidth - 1
102+
if s[x][y] - s[x][j - 1] - s[i - 1][y] + s[i - 1][j - 1] == 0:
103+
d[i][j] += 1
104+
d[i][y + 1] -= 1
105+
d[x + 1][j] -= 1
106+
d[x + 1][y + 1] += 1
107+
for i, row in enumerate(grid, 1):
108+
for j, v in enumerate(row, 1):
109+
d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1]
110+
if v == 0 and d[i][j] == 0:
112111
return False
113112
return True
114113
```
@@ -122,30 +121,27 @@ class Solution {
122121
public boolean possibleToStamp(int[][] grid, int stampHeight, int stampWidth) {
123122
int m = grid.length, n = grid[0].length;
124123
int[][] s = new int[m + 1][n + 1];
125-
for (int i = 0; i < m; ++i) {
126-
for (int j = 0; j < n; ++j) {
127-
s[i+1][j+1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + grid[i][j];
124+
for (int i = 1; i <= m; ++i) {
125+
for (int j = 1; j <= n; ++j) {
126+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i-1][j-1] + grid[i-1][j-1];
128127
}
129128
}
130-
int[][] d = new int[m + 1][n + 1];
131-
for (int i = 0; i < m; ++i) {
132-
for (int j = 0; j < n; ++j) {
133-
if (grid[i][j] == 0) {
134-
int x = i + stampHeight, y = j + stampWidth;
135-
if (x <= m && y <= n && s[x][y] - s[x][j] - s[i][y] + s[i][j] == 0) {
136-
d[i][j]++;
137-
d[i][y]--;
138-
d[x][j]--;
139-
d[x][y]++;
140-
}
129+
int[][] d = new int[m + 2][n + 2];
130+
for (int i = 1; i + stampHeight - 1 <= m; ++i) {
131+
for (int j = 1; j + stampWidth - 1 <= n; ++j) {
132+
int x = i + stampHeight - 1, y = j + stampWidth - 1;
133+
if (s[x][y] - s[x][j - 1] - s[i - 1][y] + s[i - 1][j - 1] == 0) {
134+
d[i][j]++;
135+
d[i][y + 1]--;
136+
d[x + 1][j]--;
137+
d[x + 1][y + 1]++;
141138
}
142139
}
143140
}
144-
int[][] cnt = new int[m + 1][n + 1];
145-
for (int i = 0; i < m; ++i) {
146-
for (int j = 0; j < n; ++j) {
147-
cnt[i + 1][j + 1] = cnt[i + 1][j] + cnt[i][j + 1] - cnt[i][j] + d[i][j];
148-
if (grid[i][j] == 0 && cnt[i + 1][j + 1] == 0) {
141+
for (int i = 1; i <= m; ++i) {
142+
for (int j = 1; j <= n; ++j) {
143+
d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
144+
if (grid[i - 1][j - 1] == 0 && d[i][j] == 0) {
149145
return false;
150146
}
151147
}
@@ -163,36 +159,120 @@ public:
163159
bool possibleToStamp(vector<vector<int>>& grid, int stampHeight, int stampWidth) {
164160
int m = grid.size(), n = grid[0].size();
165161
vector<vector<int>> s(m + 1, vector<int>(n + 1));
166-
for (int i = 0; i < m; ++i) {
167-
for (int j = 0; j < n; ++j) {
168-
s[i + 1][j + 1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + grid[i][j];
162+
for (int i = 1; i <= m; ++i) {
163+
for (int j = 1; j <= n; ++j) {
164+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + grid[i - 1][j - 1];
169165
}
170166
}
171-
vector<vector<int>> d(m + 1, vector<int>(n + 1));
172-
for (int i = 0; i < m; ++i) {
173-
for (int j = 0; j < n; ++j) {
174-
if (grid[i][j]) continue;
175-
int x = i + stampHeight, y = j + stampWidth;
176-
if (x <= m && y <= n && s[x][y] - s[i][y] - s[x][j] + s[i][j] == 0) {
167+
168+
vector<vector<int>> d(m + 2, vector<int>(n + 2));
169+
for (int i = 1; i + stampHeight - 1 <= m; ++i) {
170+
for (int j = 1; j + stampWidth - 1 <= n; ++j) {
171+
int x = i + stampHeight - 1, y = j + stampWidth - 1;
172+
if (s[x][y] - s[x][j - 1] - s[i - 1][y] + s[i - 1][j - 1] == 0) {
177173
d[i][j]++;
178-
d[x][j]--;
179-
d[i][y]--;
180-
d[x][y]++;
174+
d[i][y + 1]--;
175+
d[x + 1][j]--;
176+
d[x + 1][y + 1]++;
181177
}
182178
}
183179
}
184-
vector<vector<int>> cnt(m + 1, vector<int>(n + 1));
185-
for (int i = 0; i < m; ++i) {
186-
for (int j = 0; j < n; ++j) {
187-
cnt[i + 1][j + 1] = cnt[i + 1][j] + cnt[i][j + 1] - cnt[i][j] + d[i][j];
188-
if (grid[i][j] == 0 && cnt[i + 1][j + 1] == 0) return false;
180+
181+
for (int i = 1; i <= m; ++i) {
182+
for (int j = 1; j <= n; ++j) {
183+
d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
184+
if (grid[i - 1][j - 1] == 0 && d[i][j] == 0) {
185+
return false;
186+
}
189187
}
190188
}
191189
return true;
192190
}
193191
};
194192
```
195193

194+
### **Go**
195+
196+
```go
197+
func possibleToStamp(grid [][]int, stampHeight int, stampWidth int) bool {
198+
m, n := len(grid), len(grid[0])
199+
s := make([][]int, m+1)
200+
for i := range s {
201+
s[i] = make([]int, n+1)
202+
}
203+
for i := 1; i <= m; i++ {
204+
for j := 1; j <= n; j++ {
205+
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + grid[i-1][j-1]
206+
}
207+
}
208+
209+
d := make([][]int, m+2)
210+
for i := range d {
211+
d[i] = make([]int, n+2)
212+
}
213+
214+
for i := 1; i+stampHeight-1 <= m; i++ {
215+
for j := 1; j+stampWidth-1 <= n; j++ {
216+
x, y := i+stampHeight-1, j+stampWidth-1
217+
if s[x][y]-s[x][j-1]-s[i-1][y]+s[i-1][j-1] == 0 {
218+
d[i][j]++
219+
d[i][y+1]--
220+
d[x+1][j]--
221+
d[x+1][y+1]++
222+
}
223+
}
224+
}
225+
226+
for i := 1; i <= m; i++ {
227+
for j := 1; j <= n; j++ {
228+
d[i][j] += d[i-1][j] + d[i][j-1] - d[i-1][j-1]
229+
if grid[i-1][j-1] == 0 && d[i][j] == 0 {
230+
return false
231+
}
232+
}
233+
}
234+
return true
235+
}
236+
```
237+
238+
### **TypeScript**
239+
240+
```ts
241+
function possibleToStamp(grid: number[][], stampHeight: number, stampWidth: number): boolean {
242+
const m = grid.length;
243+
const n = grid[0].length;
244+
const s: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
245+
for (let i = 1; i <= m; ++i) {
246+
for (let j = 1; j <= n; ++j) {
247+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + grid[i - 1][j - 1];
248+
}
249+
}
250+
251+
const d: number[][] = Array.from({ length: m + 2 }, () => Array(n + 2).fill(0));
252+
for (let i = 1; i + stampHeight - 1 <= m; ++i) {
253+
for (let j = 1; j + stampWidth - 1 <= n; ++j) {
254+
const [x, y] = [i + stampHeight - 1, j + stampWidth - 1];
255+
if (s[x][y] - s[x][j - 1] - s[i - 1][y] + s[i - 1][j - 1] === 0) {
256+
d[i][j]++;
257+
d[i][y + 1]--;
258+
d[x + 1][j]--;
259+
d[x + 1][y + 1]++;
260+
}
261+
}
262+
}
263+
264+
for (let i = 1; i <= m; ++i) {
265+
for (let j = 1; j <= n; ++j) {
266+
d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
267+
if (grid[i - 1][j - 1] === 0 && d[i][j] === 0) {
268+
return false;
269+
}
270+
}
271+
}
272+
return true;
273+
}
274+
```
275+
196276
### **Rust**
197277

198278
```rust
@@ -264,49 +344,6 @@ impl Solution {
264344
}
265345
```
266346

267-
### **Go**
268-
269-
```go
270-
func possibleToStamp(grid [][]int, stampHeight int, stampWidth int) bool {
271-
m, n := len(grid), len(grid[0])
272-
s := make([][]int, m+1)
273-
d := make([][]int, m+1)
274-
cnt := make([][]int, m+1)
275-
for i := range s {
276-
s[i] = make([]int, n+1)
277-
d[i] = make([]int, n+1)
278-
cnt[i] = make([]int, n+1)
279-
}
280-
for i, row := range grid {
281-
for j, v := range row {
282-
s[i+1][j+1] = s[i+1][j] + s[i][j+1] - s[i][j] + v
283-
}
284-
}
285-
for i, row := range grid {
286-
for j, v := range row {
287-
if v == 0 {
288-
x, y := i+stampHeight, j+stampWidth
289-
if x <= m && y <= n && s[x][y]-s[i][y]-s[x][j]+s[i][j] == 0 {
290-
d[i][j]++
291-
d[i][y]--
292-
d[x][j]--
293-
d[x][y]++
294-
}
295-
}
296-
}
297-
}
298-
for i, row := range grid {
299-
for j, v := range row {
300-
cnt[i+1][j+1] = cnt[i+1][j] + cnt[i][j+1] - cnt[i][j] + d[i][j]
301-
if v == 0 && cnt[i+1][j+1] == 0 {
302-
return false
303-
}
304-
}
305-
}
306-
return true
307-
}
308-
```
309-
310347
### **JavaScript**
311348

312349
```js
@@ -319,31 +356,30 @@ func possibleToStamp(grid [][]int, stampHeight int, stampWidth int) bool {
319356
var possibleToStamp = function (grid, stampHeight, stampWidth) {
320357
const m = grid.length;
321358
const n = grid[0].length;
322-
let s = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
323-
let d = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
324-
let cnt = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
325-
for (let i = 0; i < m; ++i) {
326-
for (let j = 0; j < n; ++j) {
327-
s[i + 1][j + 1] = s[i + 1][j] + s[i][j + 1] - s[i][j] + grid[i][j];
359+
const s = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
360+
for (let i = 1; i <= m; ++i) {
361+
for (let j = 1; j <= n; ++j) {
362+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + grid[i - 1][j - 1];
328363
}
329364
}
330-
for (let i =0; i < m; ++i) {
331-
for (let j =0; j < n; ++j) {
332-
if (grid[i][j] ==0) {
333-
let [x, y] = [i + stampHeight, j + stampWidth];
334-
if (x <= m && y <= n && s[x][y] - s[i][y] - s[x][j] + s[i][j] ==0) {
335-
d[i][j]++;
336-
d[i][y]--;
337-
d[x][j]--;
338-
d[x][y]++;
339-
}
365+
366+
constd=Array.from({ length: m +2 }, () =>Array(n +2).fill(0));
367+
for (let i =1; i + stampHeight -1<= m; ++i) {
368+
for (let j =1; j + stampWidth -1<= n; ++j) {
369+
const [x, y] = [i + stampHeight - 1, j + stampWidth -1];
370+
if (s[x][y] - s[x][j -1] - s[i -1][y] + s[i -1][j-1] ===0) {
371+
d[i][j]++;
372+
d[i][y +1]--;
373+
d[x+1][j]--;
374+
d[x +1][y +1]++;
340375
}
341376
}
342377
}
343-
for (let i = 0; i < m; ++i) {
344-
for (let j = 0; j < n; ++j) {
345-
cnt[i + 1][j + 1] = cnt[i + 1][j] + cnt[i][j + 1] - cnt[i][j] + d[i][j];
346-
if (grid[i][j] == 0 && cnt[i + 1][j + 1] == 0) {
378+
379+
for (let i = 1; i <= m; ++i) {
380+
for (let j = 1; j <= n; ++j) {
381+
d[i][j] += d[i - 1][j] + d[i][j - 1] - d[i - 1][j - 1];
382+
if (grid[i - 1][j - 1] === 0 && d[i][j] === 0) {
347383
return false;
348384
}
349385
}
@@ -352,14 +388,6 @@ var possibleToStamp = function (grid, stampHeight, stampWidth) {
352388
};
353389
```
354390

355-
### **TypeScript**
356-
357-
<!-- 这里可写当前语言的特殊实现逻辑 -->
358-
359-
```ts
360-
361-
```
362-
363391
### **...**
364392

365393
```

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /