Skip to content

Commit c67ee12

Browse files
authored
feat: add solutions to lcof2 problem: No.013 (doocs#1399)
No.013.二维子矩阵的和
1 parent 746daf4 commit c67ee12

File tree

6 files changed

+206
-115
lines changed

6 files changed

+206
-115
lines changed

lcof2/剑指 Offer II 013. 二维子矩阵的和/README.md

+96-35
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,33 @@ numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
5959

6060
<!-- 这里可写通用的实现逻辑 -->
6161

62-
动态规划-二维前缀和。
62+
**方法一:二维前缀和**
63+
64+
我们可以用一个二维数组 $s$ 来保存矩阵 $matrix$ 的前缀和,其中 $s[i+1][j+1]$ 表示矩阵 $matrix$ 中以 $(0,0)$ 为左上角,$(i,j)$ 为右下角的子矩阵中所有元素的和。
65+
66+
那么:
67+
68+
$$
69+
\begin{aligned}
70+
s[i+1][j+1] &= s[i][j+1] + s[i+1][j] - s[i][j] + matrix[i][j]
71+
\end{aligned}
72+
$$
73+
74+
我们可以用前缀和数组 $s$ 来快速计算矩阵 $matrix$ 中任意子矩阵的元素和,计算公式如下:
75+
76+
$$
77+
\begin{aligned}
78+
&\textit{sumRegion}(row_1,col_1,row_2,col_2) \\
79+
&= s[row_2+1][col_2+1] - s[row_2+1][col_1] - s[row_1][col_2+1] + s[row_1][col_1]
80+
\end{aligned}
81+
$$
82+
83+
时间复杂度:
84+
85+
- 初始化的时间复杂度为 $O(m \times n)$,其中 $m$ 和 $n$ 分别是矩阵 $matrix$ 的行数和列数。
86+
- 每次计算子矩阵的元素和的时间复杂度为 $O(1)$。
87+
88+
空间复杂度 $O(m \times n)$,其中 $m$ 和 $n$ 分别是矩阵 $matrix$ 的行数和列数。我们需要创建一个二维数组 $s$ 来保存矩阵 $matrix$ 的前缀和。
6389

6490
<!-- tabs:start -->
6591

@@ -70,23 +96,19 @@ numMatrix.sumRegion(1, 2, 2, 4); // return 12 (蓝色矩形框的元素总和)
7096
```python
7197
class NumMatrix:
7298
def __init__(self, matrix: List[List[int]]):
73-
m, n = len(matrix), len(matrix[0])
74-
self.pre = [[0] * (n + 1) for _ in range(m + 1)]
75-
for i in range(1, m + 1):
76-
for j in range(1, n + 1):
77-
self.pre[i][j] = (
78-
self.pre[i - 1][j]
79-
+ self.pre[i][j - 1]
80-
- self.pre[i - 1][j - 1]
81-
+ matrix[i - 1][j - 1]
99+
self.s = [[0] * (len(matrix[0]) + 1) for _ in range(len(matrix) + 1)]
100+
for i, row in enumerate(matrix, 1):
101+
for j, x in enumerate(row, 1):
102+
self.s[i][j] = (
103+
self.s[i - 1][j] + self.s[i][j - 1] - self.s[i - 1][j - 1] + x
82104
)
83105

84106
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
85107
return (
86-
self.pre[row2 + 1][col2 + 1]
87-
- self.pre[row2 + 1][col1]
88-
- self.pre[row1][col2 + 1]
89-
+ self.pre[row1][col1]
108+
self.s[row2 + 1][col2 + 1]
109+
- self.s[row2 + 1][col1]
110+
- self.s[row1][col2 + 1]
111+
+ self.s[row1][col1]
90112
)
91113

92114

@@ -101,22 +123,21 @@ class NumMatrix:
101123

102124
```java
103125
class NumMatrix {
104-
private int[][] pre;
126+
private int[][] s;
105127

106128
public NumMatrix(int[][] matrix) {
107-
int m = matrix.length, n = matrix[0].length;
108-
pre = new int[m + 1][n + 1];
129+
int m = matrix.length;
130+
int n = matrix[0].length;
131+
s = new int[m + 1][n + 1];
109132
for (int i = 1; i <= m; ++i) {
110133
for (int j = 1; j <= n; ++j) {
111-
pre[i][j]
112-
= pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + matrix[i - 1][j - 1];
134+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
113135
}
114136
}
115137
}
116138

117139
public int sumRegion(int row1, int col1, int row2, int col2) {
118-
return pre[row2 + 1][col2 + 1] - pre[row2 + 1][col1] - pre[row1][col2 + 1]
119-
+ pre[row1][col1];
140+
return s[row2 + 1][col2 + 1] - s[row2 + 1][col1] - s[row1][col2 + 1] + s[row1][col1];
120141
}
121142
}
122143

@@ -132,21 +153,23 @@ class NumMatrix {
132153
```cpp
133154
class NumMatrix {
134155
public:
135-
vector<vector<int>> pre;
136-
137156
NumMatrix(vector<vector<int>>& matrix) {
138-
int m = matrix.size(), n = matrix[0].size();
139-
pre.resize(m + 1, vector<int>(n + 1));
157+
int m = matrix.size();
158+
int n = matrix[0].size();
159+
s.resize(m + 1, vector<int>(n + 1, 0));
140160
for (int i = 1; i <= m; ++i) {
141161
for (int j = 1; j <= n; ++j) {
142-
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + matrix[i - 1][j - 1];
162+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
143163
}
144164
}
145165
}
146166

147167
int sumRegion(int row1, int col1, int row2, int col2) {
148-
return pre[row2 + 1][col2 + 1] - pre[row2 + 1][col1] - pre[row1][col2 + 1] + pre[row1][col1];
168+
return s[row2 + 1][col2 + 1] - s[row2 + 1][col1] - s[row1][col2 + 1] + s[row1][col1];
149169
}
170+
171+
private:
172+
vector<vector<int>> s;
150173
};
151174

152175
/**
@@ -160,25 +183,25 @@ public:
160183

161184
```go
162185
type NumMatrix struct {
163-
pre [][]int
186+
s [][]int
164187
}
165188

166189
func Constructor(matrix [][]int) NumMatrix {
167190
m, n := len(matrix), len(matrix[0])
168-
pre := make([][]int, m+1)
191+
s := make([][]int, m+1)
169192
for i := 0; i < m+1; i++ {
170-
pre[i] = make([]int, n+1)
193+
s[i] = make([]int, n+1)
171194
}
172-
for i := 1; i < m+1; i++ {
173-
for j := 1; j < n+1; j++ {
174-
pre[i][j] = pre[i-1][j] + pre[i][j-1] + -pre[i-1][j-1] + matrix[i-1][j-1]
195+
for i := 1; i <= m; i++ {
196+
for j := 1; j <= n; j++ {
197+
s[i][j] = s[i-1][j] + s[i][j-1] + -s[i-1][j-1] + matrix[i-1][j-1]
175198
}
176199
}
177-
return NumMatrix{pre}
200+
return NumMatrix{s}
178201
}
179202

180203
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
181-
return this.pre[row2+1][col2+1] - this.pre[row2+1][col1] - this.pre[row1][col2+1] + this.pre[row1][col1]
204+
return this.s[row2+1][col2+1] - this.s[row2+1][col1] - this.s[row1][col2+1] + this.s[row1][col1]
182205
}
183206

184207
/**
@@ -188,6 +211,44 @@ func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
188211
*/
189212
```
190213

214+
### **TypeScript**
215+
216+
```ts
217+
class NumMatrix {
218+
s: number[][];
219+
220+
constructor(matrix: number[][]) {
221+
const m = matrix.length;
222+
const n = matrix[0].length;
223+
this.s = new Array(m + 1).fill(0).map(() => new Array(n + 1).fill(0));
224+
for (let i = 1; i <= m; i++) {
225+
for (let j = 1; j <= n; j++) {
226+
this.s[i][j] =
227+
this.s[i - 1][j] +
228+
this.s[i][j - 1] -
229+
this.s[i - 1][j - 1] +
230+
matrix[i - 1][j - 1];
231+
}
232+
}
233+
}
234+
235+
sumRegion(row1: number, col1: number, row2: number, col2: number): number {
236+
return (
237+
this.s[row2 + 1][col2 + 1] -
238+
this.s[row2 + 1][col1] -
239+
this.s[row1][col2 + 1] +
240+
this.s[row1][col1]
241+
);
242+
}
243+
}
244+
245+
/**
246+
* Your NumMatrix object will be instantiated and called as such:
247+
* var obj = new NumMatrix(matrix)
248+
* var param_1 = obj.sumRegion(row1,col1,row2,col2)
249+
*/
250+
```
251+
191252
### **...**
192253

193254
```
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,26 @@
1-
class NumMatrix {
2-
public:
3-
vector<vector<int>> pre;
4-
5-
NumMatrix(vector<vector<int>>& matrix) {
6-
int m = matrix.size(), n = matrix[0].size();
7-
pre.resize(m + 1, vector<int>(n + 1));
8-
for (int i = 1; i <= m; ++i) {
9-
for (int j = 1; j <= n; ++j) {
10-
pre[i][j] = pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + matrix[i - 1][j - 1];
11-
}
12-
}
13-
}
14-
15-
int sumRegion(int row1, int col1, int row2, int col2) {
16-
return pre[row2 + 1][col2 + 1] - pre[row2 + 1][col1] - pre[row1][col2 + 1] + pre[row1][col1];
17-
}
18-
};
19-
20-
/**
21-
* Your NumMatrix object will be instantiated and called as such:
22-
* NumMatrix* obj = new NumMatrix(matrix);
23-
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
1+
class NumMatrix {
2+
public:
3+
NumMatrix(vector<vector<int>>& matrix) {
4+
int m = matrix.size();
5+
int n = matrix[0].size();
6+
s.resize(m + 1, vector<int>(n + 1, 0));
7+
for (int i = 1; i <= m; ++i) {
8+
for (int j = 1; j <= n; ++j) {
9+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
10+
}
11+
}
12+
}
13+
14+
int sumRegion(int row1, int col1, int row2, int col2) {
15+
return s[row2 + 1][col2 + 1] - s[row2 + 1][col1] - s[row1][col2 + 1] + s[row1][col1];
16+
}
17+
18+
private:
19+
vector<vector<int>> s;
20+
};
21+
22+
/**
23+
* Your NumMatrix object will be instantiated and called as such:
24+
* NumMatrix* obj = new NumMatrix(matrix);
25+
* int param_1 = obj->sumRegion(row1,col1,row2,col2);
2426
*/

lcof2/剑指 Offer II 013. 二维子矩阵的和/Solution.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
type NumMatrix struct {
2-
pre [][]int
2+
s [][]int
33
}
44

55
func Constructor(matrix [][]int) NumMatrix {
66
m, n := len(matrix), len(matrix[0])
7-
pre := make([][]int, m+1)
7+
s := make([][]int, m+1)
88
for i := 0; i < m+1; i++ {
9-
pre[i] = make([]int, n+1)
9+
s[i] = make([]int, n+1)
1010
}
11-
for i := 1; i < m+1; i++ {
12-
for j := 1; j < n+1; j++ {
13-
pre[i][j] = pre[i-1][j] + pre[i][j-1] + -pre[i-1][j-1] + matrix[i-1][j-1]
11+
for i := 1; i <= m; i++ {
12+
for j := 1; j <= n; j++ {
13+
s[i][j] = s[i-1][j] + s[i][j-1] + -s[i-1][j-1] + matrix[i-1][j-1]
1414
}
1515
}
16-
return NumMatrix{pre}
16+
return NumMatrix{s}
1717
}
1818

1919
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
20-
return this.pre[row2+1][col2+1] - this.pre[row2+1][col1] - this.pre[row1][col2+1] + this.pre[row1][col1]
20+
return this.s[row2+1][col2+1] - this.s[row2+1][col1] - this.s[row1][col2+1] + this.s[row1][col1]
2121
}
2222

2323
/**
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
1-
class NumMatrix {
2-
private int[][] pre;
3-
4-
public NumMatrix(int[][] matrix) {
5-
int m = matrix.length, n = matrix[0].length;
6-
pre = new int[m + 1][n + 1];
7-
for (int i = 1; i <= m; ++i) {
8-
for (int j = 1; j <= n; ++j) {
9-
pre[i][j]
10-
= pre[i - 1][j] + pre[i][j - 1] - pre[i - 1][j - 1] + matrix[i - 1][j - 1];
11-
}
12-
}
13-
}
14-
15-
public int sumRegion(int row1, int col1, int row2, int col2) {
16-
return pre[row2 + 1][col2 + 1] - pre[row2 + 1][col1] - pre[row1][col2 + 1]
17-
+ pre[row1][col1];
18-
}
19-
}
20-
21-
/**
22-
* Your NumMatrix object will be instantiated and called as such:
23-
* NumMatrix obj = new NumMatrix(matrix);
24-
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
1+
class NumMatrix {
2+
private int[][] s;
3+
4+
public NumMatrix(int[][] matrix) {
5+
int m = matrix.length;
6+
int n = matrix[0].length;
7+
s = new int[m + 1][n + 1];
8+
for (int i = 1; i <= m; ++i) {
9+
for (int j = 1; j <= n; ++j) {
10+
s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + matrix[i - 1][j - 1];
11+
}
12+
}
13+
}
14+
15+
public int sumRegion(int row1, int col1, int row2, int col2) {
16+
return s[row2 + 1][col2 + 1] - s[row2 + 1][col1] - s[row1][col2 + 1] + s[row1][col1];
17+
}
18+
}
19+
20+
/**
21+
* Your NumMatrix object will be instantiated and called as such:
22+
* NumMatrix obj = new NumMatrix(matrix);
23+
* int param_1 = obj.sumRegion(row1,col1,row2,col2);
2524
*/
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
1-
class NumMatrix:
2-
def __init__(self, matrix: List[List[int]]):
3-
m, n = len(matrix), len(matrix[0])
4-
self.pre = [[0] * (n + 1) for _ in range(m + 1)]
5-
for i in range(1, m + 1):
6-
for j in range(1, n + 1):
7-
self.pre[i][j] = (
8-
self.pre[i - 1][j]
9-
+ self.pre[i][j - 1]
10-
- self.pre[i - 1][j - 1]
11-
+ matrix[i - 1][j - 1]
12-
)
13-
14-
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
15-
return (
16-
self.pre[row2 + 1][col2 + 1]
17-
- self.pre[row2 + 1][col1]
18-
- self.pre[row1][col2 + 1]
19-
+ self.pre[row1][col1]
20-
)
21-
22-
23-
# Your NumMatrix object will be instantiated and called as such:
24-
# obj = NumMatrix(matrix)
25-
# param_1 = obj.sumRegion(row1,col1,row2,col2)
1+
class NumMatrix:
2+
def __init__(self, matrix: List[List[int]]):
3+
self.s = [[0] * (len(matrix[0]) + 1) for _ in range(len(matrix) + 1)]
4+
for i, row in enumerate(matrix, 1):
5+
for j, x in enumerate(row, 1):
6+
self.s[i][j] = (
7+
self.s[i - 1][j] + self.s[i][j - 1] - self.s[i - 1][j - 1] + x
8+
)
9+
10+
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
11+
return (
12+
self.s[row2 + 1][col2 + 1]
13+
- self.s[row2 + 1][col1]
14+
- self.s[row1][col2 + 1]
15+
+ self.s[row1][col1]
16+
)
17+
18+
19+
# Your NumMatrix object will be instantiated and called as such:
20+
# obj = NumMatrix(matrix)
21+
# param_1 = obj.sumRegion(row1,col1,row2,col2)

0 commit comments

Comments
 (0)