Skip to content

Commit bb6566b

Browse files
committed
feat: add solutions to lc problem: No.2536
1 parent 40329ab commit bb6566b

File tree

4 files changed

+220
-18
lines changed

4 files changed

+220
-18
lines changed

solution/2500-2599/2536.Increment Submatrices by One/README.md

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ tags:
4040
<strong>输入:</strong>n = 3, queries = [[1,1,2,2],[0,0,1,1]]
4141
<strong>输出:</strong>[[1,1,0],[1,2,1],[0,1,1]]
4242
<strong>解释:</strong>上图所展示的分别是:初始矩阵、执行完第一个操作后的矩阵、执行完第二个操作后的矩阵。
43-
- 第一个操作:将左上角为 (1, 1) 且右下角为 (2, 2) 的子矩阵中的每个元素加 1 。
44-
- 第二个操作:将左上角为 (0, 0) 且右下角为 (1, 1) 的子矩阵中的每个元素加 1 。
43+
- 第一个操作:将左上角为 (1, 1) 且右下角为 (2, 2) 的子矩阵中的每个元素加 1 。
44+
- 第二个操作:将左上角为 (0, 0) 且右下角为 (1, 1) 的子矩阵中的每个元素加 1 。
4545
</pre>
4646

4747
<p><strong>示例 2:</strong></p>
@@ -51,7 +51,7 @@ tags:
5151
<pre>
5252
<strong>输入:</strong>n = 2, queries = [[0,0,1,1]]
5353
<strong>输出:</strong>[[1,1],[1,1]]
54-
<strong>解释:</strong>上图所展示的分别是:初始矩阵、执行完第一个操作后的矩阵。
54+
<strong>解释:</strong>上图所展示的分别是:初始矩阵、执行完第一个操作后的矩阵。
5555
- 第一个操作:将矩阵中的每个元素加 1 。</pre>
5656

5757
<p>&nbsp;</p>
@@ -73,25 +73,22 @@ tags:
7373

7474
### 方法一:二维差分
7575

76-
二维差分模板题。
77-
78-
```python
79-
mat = [[0] * (n + 1) for _ in range(n + 1)]
76+
二维差分数组是一种用于高效处理二维数组区间更新的技巧。我们可以通过维护一个与原矩阵大小相同的差分矩阵来实现对子矩阵的快速更新。
8077

78+
假设我们有一个二维差分矩阵 $\textit{diff}$,初始时所有元素均为 $0$。对于每个查询 $[\textit{row1}, \textit{col1}, \textit{row2}, \textit{col2}]$,我们可以通过以下步骤更新差分矩阵:
8179

82-
def insert(x1, y1, x2, y2, c):
83-
mat[x1][y1] += c
84-
mat[x1][y2 + 1] -= c
85-
mat[x2 + 1][y1] -= c
86-
mat[x2 + 1][y2 + 1] += c
80+
1. 在位置 $(\textit{row1}, \textit{col1})$ 加 $1$。
81+
2. 在位置 $(\textit{row2} + 1, \textit{col1})$ 减 $1$,前提是 $\textit{row2} + 1 < n$。
82+
3. 在位置 $(\textit{row1}, \textit{col2} + 1)$ 减 $1$,前提是 $\textit{col2} + 1 < n$。
83+
4. 在位置 $(\textit{row2} + 1, \textit{col2} + 1)$ 加 $1$,前提是 $\textit{row2} + 1 < n$ 且 $\textit{col2} + 1 < n$。
8784

85+
完成所有查询后,我们需要通过前缀和的方式将差分矩阵转换回原矩阵。即,对于每个位置 $(i, j)$,我们计算:
8886

89-
for i in range(1, n + 1):
90-
for j in range(1, n + 1):
91-
mat[i][j] += mat[i - 1][j] + mat[i][j - 1] - mat[i - 1][j - 1]
92-
```
87+
$$
88+
\textit{mat}[i][j] = \textit{diff}[i][j] + (\textit{mat}[i-1][j] \text{ if } i > 0 \text{ else } 0) + (\textit{mat}[i][j-1] \text{ if } j > 0 \text{ else } 0) - (\textit{mat}[i-1][j-1] \text{ if } i > 0 \text{ and } j > 0 \text{ else } 0)
89+
$$
9390

94-
时间复杂度 $O(m + n^2)$,其中 $m$ 和 $n$ 分别是 `queries` 的长度和给定的 $n$。忽略答案的空间消耗,空间复杂度 $O(1)$。
91+
时间复杂度 $O(m + n^2)$,其中 $m$ 和 $n$ 分别是 $\textit{queries}$ 的长度和给定的 $n$。忽略答案的空间消耗,空间复杂度 $O(1)$。
9592

9693
<!-- tabs:start -->
9794

@@ -234,6 +231,72 @@ func rangeAddQueries(n int, queries [][]int) [][]int {
234231
}
235232
```
236233

234+
#### TypeScript
235+
236+
```ts
237+
function rangeAddQueries(n: number, queries: number[][]): number[][] {
238+
const mat: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
239+
240+
for (const [x1, y1, x2, y2] of queries) {
241+
mat[x1][y1] += 1;
242+
if (x2 + 1 < n) mat[x2 + 1][y1] -= 1;
243+
if (y2 + 1 < n) mat[x1][y2 + 1] -= 1;
244+
if (x2 + 1 < n && y2 + 1 < n) mat[x2 + 1][y2 + 1] += 1;
245+
}
246+
247+
for (let i = 0; i < n; ++i) {
248+
for (let j = 0; j < n; ++j) {
249+
if (i > 0) mat[i][j] += mat[i - 1][j];
250+
if (j > 0) mat[i][j] += mat[i][j - 1];
251+
if (i > 0 && j > 0) mat[i][j] -= mat[i - 1][j - 1];
252+
}
253+
}
254+
255+
return mat;
256+
}
257+
```
258+
259+
#### Rust
260+
261+
```rust
262+
impl Solution {
263+
pub fn range_add_queries(n: i32, queries: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
264+
let n = n as usize;
265+
let mut mat = vec![vec![0; n]; n];
266+
267+
for q in queries {
268+
let (x1, y1, x2, y2) = (q[0] as usize, q[1] as usize, q[2] as usize, q[3] as usize);
269+
mat[x1][y1] += 1;
270+
if x2 + 1 < n {
271+
mat[x2 + 1][y1] -= 1;
272+
}
273+
if y2 + 1 < n {
274+
mat[x1][y2 + 1] -= 1;
275+
}
276+
if x2 + 1 < n && y2 + 1 < n {
277+
mat[x2 + 1][y2 + 1] += 1;
278+
}
279+
}
280+
281+
for i in 0..n {
282+
for j in 0..n {
283+
if i > 0 {
284+
mat[i][j] += mat[i - 1][j];
285+
}
286+
if j > 0 {
287+
mat[i][j] += mat[i][j - 1];
288+
}
289+
if i > 0 && j > 0 {
290+
mat[i][j] -= mat[i - 1][j - 1];
291+
}
292+
}
293+
}
294+
295+
mat
296+
}
297+
}
298+
```
299+
237300
<!-- tabs:end -->
238301

239302
<!-- solution:end -->

solution/2500-2599/2536.Increment Submatrices by One/README_EN.md

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,24 @@ tags:
6666

6767
<!-- solution:start -->
6868

69-
### Solution 1
69+
### Solution 1: 2D Difference Array
70+
71+
A 2D difference array is a technique used to efficiently handle range updates on 2D arrays. We can implement fast updates on submatrices by maintaining a difference matrix of the same size as the original matrix.
72+
73+
Suppose we have a 2D difference matrix $\textit{diff}$, initially with all elements set to $0$. For each query $[\textit{row1}, \textit{col1}, \textit{row2}, \textit{col2}]$, we can update the difference matrix through the following steps:
74+
75+
1. Increment position $(\textit{row1}, \textit{col1})$ by $1$.
76+
2. Decrement position $(\textit{row2} + 1, \textit{col1})$ by $1$, provided that $\textit{row2} + 1 < n$.
77+
3. Decrement position $(\textit{row1}, \textit{col2} + 1)$ by $1$, provided that $\textit{col2} + 1 < n$.
78+
4. Increment position $(\textit{row2} + 1, \textit{col2} + 1)$ by $1$, provided that $\textit{row2} + 1 < n$ and $\textit{col2} + 1 < n$.
79+
80+
After completing all queries, we need to convert the difference matrix back to the original matrix using prefix sums. That is, for each position $(i, j)$, we calculate:
81+
82+
$$
83+
\textit{mat}[i][j] = \textit{diff}[i][j] + (\textit{mat}[i-1][j] \text{ if } i > 0 \text{ else } 0) + (\textit{mat}[i][j-1] \text{ if } j > 0 \text{ else } 0) - (\textit{mat}[i-1][j-1] \text{ if } i > 0 \text{ and } j > 0 \text{ else } 0)
84+
$$
85+
86+
The time complexity is $O(m + n^2)$, where $m$ and $n$ are the length of $\textit{queries}$ and the given $n$, respectively. Ignoring the space consumed by the answer, the space complexity is $O(1)$.
7087

7188
<!-- tabs:start -->
7289

@@ -209,6 +226,72 @@ func rangeAddQueries(n int, queries [][]int) [][]int {
209226
}
210227
```
211228

229+
#### TypeScript
230+
231+
```ts
232+
function rangeAddQueries(n: number, queries: number[][]): number[][] {
233+
const mat: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
234+
235+
for (const [x1, y1, x2, y2] of queries) {
236+
mat[x1][y1] += 1;
237+
if (x2 + 1 < n) mat[x2 + 1][y1] -= 1;
238+
if (y2 + 1 < n) mat[x1][y2 + 1] -= 1;
239+
if (x2 + 1 < n && y2 + 1 < n) mat[x2 + 1][y2 + 1] += 1;
240+
}
241+
242+
for (let i = 0; i < n; ++i) {
243+
for (let j = 0; j < n; ++j) {
244+
if (i > 0) mat[i][j] += mat[i - 1][j];
245+
if (j > 0) mat[i][j] += mat[i][j - 1];
246+
if (i > 0 && j > 0) mat[i][j] -= mat[i - 1][j - 1];
247+
}
248+
}
249+
250+
return mat;
251+
}
252+
```
253+
254+
#### Rust
255+
256+
```rust
257+
impl Solution {
258+
pub fn range_add_queries(n: i32, queries: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
259+
let n = n as usize;
260+
let mut mat = vec![vec![0; n]; n];
261+
262+
for q in queries {
263+
let (x1, y1, x2, y2) = (q[0] as usize, q[1] as usize, q[2] as usize, q[3] as usize);
264+
mat[x1][y1] += 1;
265+
if x2 + 1 < n {
266+
mat[x2 + 1][y1] -= 1;
267+
}
268+
if y2 + 1 < n {
269+
mat[x1][y2 + 1] -= 1;
270+
}
271+
if x2 + 1 < n && y2 + 1 < n {
272+
mat[x2 + 1][y2 + 1] += 1;
273+
}
274+
}
275+
276+
for i in 0..n {
277+
for j in 0..n {
278+
if i > 0 {
279+
mat[i][j] += mat[i - 1][j];
280+
}
281+
if j > 0 {
282+
mat[i][j] += mat[i][j - 1];
283+
}
284+
if i > 0 && j > 0 {
285+
mat[i][j] -= mat[i - 1][j - 1];
286+
}
287+
}
288+
}
289+
290+
mat
291+
}
292+
}
293+
```
294+
212295
<!-- tabs:end -->
213296

214297
<!-- solution:end -->
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
impl Solution {
2+
pub fn range_add_queries(n: i32, queries: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
3+
let n = n as usize;
4+
let mut mat = vec![vec![0; n]; n];
5+
6+
for q in queries {
7+
let (x1, y1, x2, y2) = (q[0] as usize, q[1] as usize, q[2] as usize, q[3] as usize);
8+
mat[x1][y1] += 1;
9+
if x2 + 1 < n {
10+
mat[x2 + 1][y1] -= 1;
11+
}
12+
if y2 + 1 < n {
13+
mat[x1][y2 + 1] -= 1;
14+
}
15+
if x2 + 1 < n && y2 + 1 < n {
16+
mat[x2 + 1][y2 + 1] += 1;
17+
}
18+
}
19+
20+
for i in 0..n {
21+
for j in 0..n {
22+
if i > 0 {
23+
mat[i][j] += mat[i - 1][j];
24+
}
25+
if j > 0 {
26+
mat[i][j] += mat[i][j - 1];
27+
}
28+
if i > 0 && j > 0 {
29+
mat[i][j] -= mat[i - 1][j - 1];
30+
}
31+
}
32+
}
33+
34+
mat
35+
}
36+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
function rangeAddQueries(n: number, queries: number[][]): number[][] {
2+
const mat: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
3+
4+
for (const [x1, y1, x2, y2] of queries) {
5+
mat[x1][y1] += 1;
6+
if (x2 + 1 < n) mat[x2 + 1][y1] -= 1;
7+
if (y2 + 1 < n) mat[x1][y2 + 1] -= 1;
8+
if (x2 + 1 < n && y2 + 1 < n) mat[x2 + 1][y2 + 1] += 1;
9+
}
10+
11+
for (let i = 0; i < n; ++i) {
12+
for (let j = 0; j < n; ++j) {
13+
if (i > 0) mat[i][j] += mat[i - 1][j];
14+
if (j > 0) mat[i][j] += mat[i][j - 1];
15+
if (i > 0 && j > 0) mat[i][j] -= mat[i - 1][j - 1];
16+
}
17+
}
18+
19+
return mat;
20+
}

0 commit comments

Comments
 (0)