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 49bbc43

Browse files
feat: add solutions to lc problem: No.0311 (#1626)
No.0311.Sparse Matrix Multiplication
1 parent 6112294 commit 49bbc43

File tree

7 files changed

+514
-187
lines changed

7 files changed

+514
-187
lines changed

‎solution/0300-0399/0311.Sparse Matrix Multiplication/README.md

Lines changed: 201 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -42,43 +42,58 @@
4242

4343
<!-- 这里可写通用的实现逻辑 -->
4444

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+
4559
<!-- tabs:start -->
4660

4761
### **Python3**
4862

4963
<!-- 这里可写当前语言的特殊实现逻辑 -->
5064

51-
直接模拟。
52-
5365
```python
5466
class Solution:
5567
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
6375
```
6476

65-
用哈希表记录稀疏矩阵 mat1 中的非 0 值。
66-
6777
```python
6878
class Solution:
6979
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
8297
```
8398

8499
### **Java**
@@ -88,26 +103,51 @@ class Solution:
88103
```java
89104
class Solution {
90105
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];
98112
}
99113
}
100114
}
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;
107133
}
108134
}
109135
}
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;
111151
}
112152
}
113153
```
@@ -118,20 +158,48 @@ class Solution {
118158
class Solution {
119159
public:
120160
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+
}
127168
}
128169
}
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+
}
132187
}
133188
}
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;
135203
}
136204
};
137205
```
@@ -140,27 +208,99 @@ public:
140208

141209
```go
142210
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)
147215
}
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]
153220
}
154221
}
155222
}
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+
}
160243
}
161244
}
245+
return g
162246
}
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;
164304
}
165305
```
166306

0 commit comments

Comments
(0)

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