42
42
43
43
<!-- 这里可写通用的实现逻辑 -->
44
44
45
+ ** 方法一:直接相乘**
46
+
47
+ 我们可以直接按照矩阵乘法的定义,计算出结果矩阵中的每一个元素。
48
+
49
+ 时间复杂度 $O(m \times n \times k)$,空间复杂度 $O(m \times n)$。
50
+
51
+ ** 方法二:预处理**
52
+
53
+ 我们可以预处理出两个矩阵的稀疏表示,即 $g1[ i] $ 表示矩阵 $mat1$ 第 $i$ 行中所有非零元素的列下标和值,而 $g2[ i] $ 表示矩阵 $mat2$ 第 $i$ 行中所有非零元素的列下标和值。
54
+
55
+ 接下来,我们遍历每一行 $i$,遍历 $g1[ i] $ 中的每一个元素 $(k, x)$,遍历 $g2[ k] $ 中的每一个元素 $(j, y)$,那么最终 $mat1[ i] [ k ] \times mat2[ k] [ j ] $ 就会对应到结果矩阵中的 $ans[ i] [ j ] $,我们将所有的结果累加即可。
56
+
57
+ 时间复杂度 $O(m \times n \times k)$,空间复杂度 $O(m \times n)$。
58
+
45
59
<!-- tabs:start -->
46
60
47
61
### ** Python3**
48
62
49
63
<!-- 这里可写当前语言的特殊实现逻辑 -->
50
64
51
- 直接模拟。
52
-
53
65
``` python
54
66
class Solution :
55
67
def multiply (self , mat1 : List[List[int ]], mat2 : List[List[int ]]) -> List[List[int ]]:
56
- r1, c1, c2 = len (mat1), len (mat1[ 0 ] ), len (mat2[0 ])
57
- res = [[0 ] * c2 for _ in range (r1 )]
58
- for i in range (r1 ):
59
- for j in range (c2 ):
60
- for k in range (c1 ):
61
- res [i][j] += mat1[i][k] * mat2[k][j]
62
- return res
68
+ m, n = len (mat1), len (mat2[0 ])
69
+ ans = [[0 ] * n for _ in range (m )]
70
+ for i in range (m ):
71
+ for j in range (n ):
72
+ for k in range (len (mat2) ):
73
+ ans [i][j] += mat1[i][k] * mat2[k][j]
74
+ return ans
63
75
```
64
76
65
- 用哈希表记录稀疏矩阵 mat1 中的非 0 值。
66
-
67
77
``` python
68
78
class Solution :
69
79
def multiply (self , mat1 : List[List[int ]], mat2 : List[List[int ]]) -> List[List[int ]]:
70
- r1, c1, c2 = len (mat1), len (mat1[0 ]), len (mat2[0 ])
71
- res = [[0 ] * c2 for _ in range (r1)]
72
- mp = defaultdict(list )
73
- for i in range (r1):
74
- for j in range (c1):
75
- if mat1[i][j] != 0 :
76
- mp[i].append(j)
77
- for i in range (r1):
78
- for j in range (c2):
79
- for k in mp[i]:
80
- res[i][j] += mat1[i][k] * mat2[k][j]
81
- return res
80
+ def f (mat : List[List[int ]]) -> List[List[int ]]:
81
+ g = [[] for _ in range (len (mat))]
82
+ for i, row in enumerate (mat):
83
+ for j, x in enumerate (row):
84
+ if x:
85
+ g[i].append((j, x))
86
+ return g
87
+
88
+ g1 = f(mat1)
89
+ g2 = f(mat2)
90
+ m, n = len (mat1), len (mat2[0 ])
91
+ ans = [[0 ] * n for _ in range (m)]
92
+ for i in range (m):
93
+ for k, x in g1[i]:
94
+ for j, y in g2[k]:
95
+ ans[i][j] += x * y
96
+ return ans
82
97
```
83
98
84
99
### ** Java**
@@ -88,26 +103,51 @@ class Solution:
88
103
``` java
89
104
class Solution {
90
105
public int [][] multiply (int [][] mat1 , int [][] mat2 ) {
91
- int r1 = mat1. length, c1 = mat1[0 ]. length, c2 = mat2[0 ]. length;
92
- int [][] res = new int [r1][c2];
93
- Map<Integer , List<Integer > > mp = new HashMap<> ();
94
- for (int i = 0 ; i < r1; ++ i) {
95
- for (int j = 0 ; j < c1; ++ j) {
96
- if (mat1[i][j] != 0 ) {
97
- mp. computeIfAbsent(i, k - > new ArrayList<> ()). add(j);
106
+ int m = mat1. length, n = mat2[0 ]. length;
107
+ int [][] ans = new int [m][n];
108
+ for (int i = 0 ; i < m; ++ i) {
109
+ for (int j = 0 ; j < n; ++ j) {
110
+ for (int k = 0 ; k < mat2. length; ++ k) {
111
+ ans[i][j] += mat1[i][k] * mat2[k][j];
98
112
}
99
113
}
100
114
}
101
- for (int i = 0 ; i < r1; ++ i) {
102
- for (int j = 0 ; j < c2; ++ j) {
103
- if (mp. containsKey(i)) {
104
- for (int k : mp. get(i)) {
105
- res[i][j] += mat1[i][k] * mat2[k][j];
106
- }
115
+ return ans;
116
+ }
117
+ }
118
+ ```
119
+
120
+ ``` java
121
+ class Solution {
122
+ public int [][] multiply (int [][] mat1 , int [][] mat2 ) {
123
+ int m = mat1. length, n = mat2[0 ]. length;
124
+ int [][] ans = new int [m][n];
125
+ var g1 = f(mat1);
126
+ var g2 = f(mat2);
127
+ for (int i = 0 ; i < m; ++ i) {
128
+ for (int [] p : g1[i]) {
129
+ int k = p[0 ], x = p[1 ];
130
+ for (int [] q : g2[k]) {
131
+ int j = q[0 ], y = q[1 ];
132
+ ans[i][j] += x * y;
107
133
}
108
134
}
109
135
}
110
- return res;
136
+ return ans;
137
+ }
138
+
139
+ private List<int[]> [] f (int [][] mat ) {
140
+ int m = mat. length, n = mat[0 ]. length;
141
+ List<int[]> [] g = new List [m];
142
+ Arrays . setAll(g, i - > new ArrayList<> ());
143
+ for (int i = 0 ; i < m; ++ i) {
144
+ for (int j = 0 ; j < n; ++ j) {
145
+ if (mat[i][j] != 0 ) {
146
+ g[i]. add(new int [] {j, mat[i][j]});
147
+ }
148
+ }
149
+ }
150
+ return g;
111
151
}
112
152
}
113
153
```
@@ -118,20 +158,48 @@ class Solution {
118
158
class Solution {
119
159
public:
120
160
vector<vector<int >> multiply(vector<vector<int >>& mat1, vector<vector<int >>& mat2) {
121
- int r1 = mat1.size(), c1 = mat1[ 0] .size(), c2 = mat2[ 0] .size();
122
- vector<vector<int >> res(r1, vector<int >(c2));
123
- unordered_map<int, vector<int >> mp;
124
- for (int i = 0; i < r1; ++i) {
125
- for (int j = 0; j < c1; ++j) {
126
- if (mat1[ i] [ j ] != 0) mp[ i] .push_back(j);
161
+ int m = mat1.size(), n = mat2[ 0] .size();
162
+ vector<vector<int >> ans(m, vector<int >(n));
163
+ for (int i = 0; i < m; ++i) {
164
+ for (int j = 0; j < n; ++j) {
165
+ for (int k = 0; k < mat2.size(); ++k) {
166
+ ans[ i] [ j ] += mat1[ i] [ k ] * mat2[ k] [ j ] ;
167
+ }
127
168
}
128
169
}
129
- for (int i = 0; i < r1; ++i) {
130
- for (int j = 0; j < c2; ++j) {
131
- for (int k : mp[ i] ) res[ i] [ j ] += mat1[ i] [ k ] * mat2[ k] [ j ] ;
170
+ return ans;
171
+ }
172
+ };
173
+ ```
174
+
175
+ ```cpp
176
+ class Solution {
177
+ public:
178
+ vector<vector<int>> multiply(vector<vector<int>>& mat1, vector<vector<int>>& mat2) {
179
+ int m = mat1.size(), n = mat2[0].size();
180
+ vector<vector<int>> ans(m, vector<int>(n));
181
+ auto g1 = f(mat1), g2 = f(mat2);
182
+ for (int i = 0; i < m; ++i) {
183
+ for (auto& [k, x] : g1[i]) {
184
+ for (auto& [j, y] : g2[k]) {
185
+ ans[i][j] += x * y;
186
+ }
132
187
}
133
188
}
134
- return res;
189
+ return ans;
190
+ }
191
+
192
+ vector<vector<pair<int, int>>> f(vector<vector<int>>& mat) {
193
+ int m = mat.size(), n = mat[0].size();
194
+ vector<vector<pair<int, int>>> g(m);
195
+ for (int i = 0; i < m; ++i) {
196
+ for (int j = 0; j < n; ++j) {
197
+ if (mat[i][j]) {
198
+ g[i].emplace_back(j, mat[i][j]);
199
+ }
200
+ }
201
+ }
202
+ return g;
135
203
}
136
204
};
137
205
```
@@ -140,27 +208,99 @@ public:
140
208
141
209
``` go
142
210
func multiply (mat1 [][]int , mat2 [][]int ) [][]int {
143
- r1, c1, c2 := len(mat1), len(mat1[0] ), len(mat2[0])
144
- res := make([][]int, r1 )
145
- for i := range res {
146
- res [i] = make([]int, c2 )
211
+ m , n := len (mat1), len (mat2[0 ])
212
+ ans := make ([][]int , m )
213
+ for i := range ans {
214
+ ans [i] = make ([]int , n )
147
215
}
148
- mp := make(map[int][]int)
149
- for i := 0; i < r1; i++ {
150
- for j := 0; j < c1; j++ {
151
- if mat1[i][j] != 0 {
152
- mp[i] = append(mp[i], j)
216
+ for i := 0 ; i < m; i++ {
217
+ for j := 0 ; j < n; j++ {
218
+ for k := 0 ; k < len (mat2); k++ {
219
+ ans[i][j] += mat1[i][k] * mat2[k][j]
153
220
}
154
221
}
155
222
}
156
- for i := 0; i < r1; i++ {
157
- for j := 0; j < c2; j++ {
158
- for _, k := range mp[i] {
159
- res[i][j] += mat1[i][k] * mat2[k][j]
223
+ return ans
224
+ }
225
+ ```
226
+
227
+ ``` go
228
+ func multiply (mat1 [][]int , mat2 [][]int ) [][]int {
229
+ m , n := len (mat1), len (mat2[0 ])
230
+ ans := make ([][]int , m)
231
+ for i := range ans {
232
+ ans[i] = make ([]int , n)
233
+ }
234
+ f := func (mat [][]int ) [][][2 ]int {
235
+ m , n := len (mat), len (mat[0 ])
236
+ g := make ([][][2 ]int , m)
237
+ for i := range g {
238
+ g[i] = make ([][2 ]int , 0 , n)
239
+ for j := range mat[i] {
240
+ if mat[i][j] != 0 {
241
+ g[i] = append (g[i], [2 ]int {j, mat[i][j]})
242
+ }
160
243
}
161
244
}
245
+ return g
162
246
}
163
- return res
247
+ g1 , g2 := f (mat1), f (mat2)
248
+ for i := range g1 {
249
+ for _ , p := range g1[i] {
250
+ k , x := p[0 ], p[1 ]
251
+ for _ , q := range g2[k] {
252
+ j , y := q[0 ], q[1 ]
253
+ ans[i][j] += x * y
254
+ }
255
+ }
256
+ }
257
+ return ans
258
+ }
259
+ ```
260
+
261
+ ### ** TypeScript**
262
+
263
+ ``` ts
264
+ function multiply(mat1 : number [][], mat2 : number [][]): number [][] {
265
+ const [m, n] = [mat1 .length , mat2 [0 ].length ];
266
+ const ans: number [][] = Array .from ({ length: m }, () => Array .from ({ length: n }, () => 0 ));
267
+ for (let i = 0 ; i < m ; ++ i ) {
268
+ for (let j = 0 ; j < n ; ++ j ) {
269
+ for (let k = 0 ; k < mat2 .length ; ++ k ) {
270
+ ans [i ][j ] += mat1 [i ][k ] * mat2 [k ][j ];
271
+ }
272
+ }
273
+ }
274
+ return ans ;
275
+ }
276
+ ```
277
+
278
+ ``` ts
279
+ function multiply(mat1 : number [][], mat2 : number [][]): number [][] {
280
+ const [m, n] = [mat1 .length , mat2 [0 ].length ];
281
+ const ans: number [][] = Array .from ({ length: m }, () => Array .from ({ length: n }, () => 0 ));
282
+ const f = (mat : number [][]): number [][][] => {
283
+ const [m, n] = [mat .length , mat [0 ].length ];
284
+ const ans: number [][][] = Array .from ({ length: m }, () => []);
285
+ for (let i = 0 ; i < m ; ++ i ) {
286
+ for (let j = 0 ; j < n ; ++ j ) {
287
+ if (mat [i ][j ] !== 0 ) {
288
+ ans [i ].push ([j , mat [i ][j ]]);
289
+ }
290
+ }
291
+ }
292
+ return ans ;
293
+ };
294
+ const g1 = f (mat1 );
295
+ const g2 = f (mat2 );
296
+ for (let i = 0 ; i < m ; ++ i ) {
297
+ for (const [k, x] of g1 [i ]) {
298
+ for (const [j, y] of g2 [k ]) {
299
+ ans [i ][j ] += x * y ;
300
+ }
301
+ }
302
+ }
303
+ return ans ;
164
304
}
165
305
```
166
306
0 commit comments