Skip to content

Commit 04fe700

Browse files
authored
feat: add solutions to lc problem: No.1314 (doocs#2460)
No.1314.Matrix Block Sum
1 parent 93b9a06 commit 04fe700

File tree

7 files changed

+257
-191
lines changed

7 files changed

+257
-191
lines changed

solution/1300-1399/1314.Matrix Block Sum/README.md

Lines changed: 93 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -45,133 +45,162 @@
4545

4646
## 解法
4747

48-
### 方法一
48+
### 方法一:二维前缀和
49+
50+
本题属于二维前缀和模板题。
51+
52+
我们定义 $s[i][j]$ 表示矩阵 $mat$ 前 $i$ 行,前 $j$ 列的元素和。那么 $s[i][j]$ 的计算公式为:
53+
54+
$$
55+
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + mat[i-1][j-1]
56+
$$
57+
58+
这样我们就可以通过 $s$ 数组快速计算出任意矩形区域的元素和。
59+
60+
对于一个左上角坐标为 $(x_1, y_1)$,右下角坐标为 $(x_2, y_2)$ 的矩形区域的元素和,我们可以通过 $s$ 数组计算出来:
61+
62+
$$
63+
s[x_2+1][y_2+1] - s[x_1][y_2+1] - s[x_2+1][y_1] + s[x_1][y_1]
64+
$$
65+
66+
时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
4967

5068
<!-- tabs:start -->
5169

5270
```python
5371
class Solution:
5472
def matrixBlockSum(self, mat: List[List[int]], k: int) -> List[List[int]]:
5573
m, n = len(mat), len(mat[0])
56-
pre = [[0] * (n + 1) for _ in range(m + 1)]
57-
for i in range(1, m + 1):
58-
for j in range(1, n + 1):
59-
pre[i][j] = (
60-
pre[i - 1][j]
61-
+ pre[i][j - 1]
62-
- pre[i - 1][j - 1]
63-
+ mat[i - 1][j - 1]
64-
)
65-
66-
def get(i, j):
67-
i = max(min(m, i), 0)
68-
j = max(min(n, j), 0)
69-
return pre[i][j]
70-
74+
s = [[0] * (n + 1) for _ in range(m + 1)]
75+
for i, row in enumerate(mat, 1):
76+
for j, x in enumerate(row, 1):
77+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + x
7178
ans = [[0] * n for _ in range(m)]
7279
for i in range(m):
7380
for j in range(n):
81+
x1, y1 = max(i - k, 0), max(j - k, 0)
82+
x2, y2 = min(m - 1, i + k), min(n - 1, j + k)
7483
ans[i][j] = (
75-
get(i + k + 1, j + k + 1)
76-
- get(i + k + 1, j - k)
77-
- get(i - k, j + k + 1)
78-
+ get(i - k, j - k)
84+
s[x2 + 1][y2 + 1] - s[x1][y2 + 1] - s[x2 + 1][y1] + s[x1][y1]
7985
)
8086
return ans
8187
```
8288

8389
```java
8490
class Solution {
85-
private int[][] pre;
86-
private int m;
87-
private int n;
8891
public int[][] matrixBlockSum(int[][] mat, int k) {
89-
int m = mat.length, n = mat[0].length;
90-
int[][] pre = new int[m + 1][n + 1];
91-
for (int i = 1; i < m + 1; ++i) {
92-
for (int j = 1; j < n + 1; ++j) {
93-
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] + -pre[i - 1][j - 1] + mat[i - 1][j - 1];
92+
int m = mat.length;
93+
int n = mat[0].length;
94+
int[][] s = new int[m + 1][n + 1];
95+
for (int i = 0; i < m; ++i) {
96+
for (int j = 0; j < n; ++j) {
97+
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j];
9498
}
9599
}
96-
this.pre = pre;
97-
this.m = m;
98-
this.n = n;
100+
99101
int[][] ans = new int[m][n];
100102
for (int i = 0; i < m; ++i) {
101103
for (int j = 0; j < n; ++j) {
102-
ans[i][j] = get(i + k + 1, j + k + 1) - get(i + k + 1, j - k)
103-
- get(i - k, j + k + 1) + get(i - k, j - k);
104+
int x1 = Math.max(i - k, 0);
105+
int y1 = Math.max(j - k, 0);
106+
int x2 = Math.min(m - 1, i + k);
107+
int y2 = Math.min(n - 1, j + k);
108+
ans[i][j] = s[x2 + 1][y2 + 1] - s[x1][y2 + 1] - s[x2 + 1][y1] + s[x1][y1];
104109
}
105110
}
106111
return ans;
107112
}
108-
109-
private int get(int i, int j) {
110-
i = Math.max(Math.min(m, i), 0);
111-
j = Math.max(Math.min(n, j), 0);
112-
return pre[i][j];
113-
}
114113
}
115114
```
116115

117116
```cpp
118117
class Solution {
119118
public:
120119
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
121-
int m = mat.size(), n = mat[0].size();
122-
vector<vector<int>> pre(m + 1, vector<int>(n + 1));
123-
for (int i = 1; i < m + 1; ++i) {
124-
for (int j = 1; j < n + 1; ++j) {
125-
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] + -pre[i - 1][j - 1] + mat[i - 1][j - 1];
120+
int m = mat.size();
121+
int n = mat[0].size();
122+
123+
vector<vector<int>> s(m + 1, vector<int>(n + 1));
124+
for (int i = 0; i < m; ++i) {
125+
for (int j = 0; j < n; ++j) {
126+
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j];
126127
}
127128
}
129+
128130
vector<vector<int>> ans(m, vector<int>(n));
129131
for (int i = 0; i < m; ++i) {
130132
for (int j = 0; j < n; ++j) {
131-
ans[i][j] = get(i + k + 1, j + k + 1, m, n, pre) - get(i + k + 1, j - k, m, n, pre) - get(i - k, j + k + 1, m, n, pre) + get(i - k, j - k, m, n, pre);
133+
int x1 = max(i - k, 0);
134+
int y1 = max(j - k, 0);
135+
int x2 = min(m - 1, i + k);
136+
int y2 = min(n - 1, j + k);
137+
ans[i][j] = s[x2 + 1][y2 + 1] - s[x1][y2 + 1] - s[x2 + 1][y1] + s[x1][y1];
132138
}
133139
}
134140
return ans;
135141
}
136-
137-
int get(int i, int j, int m, int n, vector<vector<int>>& pre) {
138-
i = max(min(m, i), 0);
139-
j = max(min(n, j), 0);
140-
return pre[i][j];
141-
}
142142
};
143143
```
144144
145145
```go
146146
func matrixBlockSum(mat [][]int, k int) [][]int {
147147
m, n := len(mat), len(mat[0])
148-
pre := make([][]int, m+1)
149-
for i := 0; i < m+1; i++ {
150-
pre[i] = make([]int, n+1)
148+
s := make([][]int, m+1)
149+
for i := range s {
150+
s[i] = make([]int, n+1)
151151
}
152-
for i := 1; i < m+1; i++ {
153-
for j := 1; j < n+1; j++ {
154-
pre[i][j] = pre[i-1][j] + pre[i][j-1] + -pre[i-1][j-1] + mat[i-1][j-1]
152+
for i, row := range mat {
153+
for j, x := range row {
154+
s[i+1][j+1] = s[i][j+1] + s[i+1][j] - s[i][j] + x
155155
}
156156
}
157157
158-
get := func(i, j int) int {
159-
i = max(min(m, i), 0)
160-
j = max(min(n, j), 0)
161-
return pre[i][j]
158+
ans := make([][]int, m)
159+
for i := range ans {
160+
ans[i] = make([]int, n)
162161
}
163162
164-
ans := make([][]int, m)
165163
for i := 0; i < m; i++ {
166-
ans[i] = make([]int, n)
167164
for j := 0; j < n; j++ {
168-
ans[i][j] = get(i+k+1, j+k+1) - get(i+k+1, j-k) - get(i-k, j+k+1) + get(i-k, j-k)
165+
x1 := max(i-k, 0)
166+
y1 := max(j-k, 0)
167+
x2 := min(m-1, i+k)
168+
y2 := min(n-1, j+k)
169+
ans[i][j] = s[x2+1][y2+1] - s[x1][y2+1] - s[x2+1][y1] + s[x1][y1]
169170
}
170171
}
172+
171173
return ans
172174
}
173175
```
174176

177+
```ts
178+
function matrixBlockSum(mat: number[][], k: number): number[][] {
179+
const m: number = mat.length;
180+
const n: number = mat[0].length;
181+
182+
const s: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
183+
for (let i = 0; i < m; i++) {
184+
for (let j = 0; j < n; j++) {
185+
s[i + 1][j + 1] = s[i][j + 1] + s[i + 1][j] - s[i][j] + mat[i][j];
186+
}
187+
}
188+
189+
const ans: number[][] = Array.from({ length: m }, () => Array(n).fill(0));
190+
for (let i = 0; i < m; i++) {
191+
for (let j = 0; j < n; j++) {
192+
const x1: number = Math.max(i - k, 0);
193+
const y1: number = Math.max(j - k, 0);
194+
const x2: number = Math.min(m - 1, i + k);
195+
const y2: number = Math.min(n - 1, j + k);
196+
ans[i][j] = s[x2 + 1][y2 + 1] - s[x1][y2 + 1] - s[x2 + 1][y1] + s[x1][y1];
197+
}
198+
}
199+
200+
return ans;
201+
}
202+
```
203+
175204
<!-- tabs:end -->
176205

177206
<!-- end -->

0 commit comments

Comments
 (0)