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

feat: add solutions to lc problem: No.0311 #1626

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
yanglbme merged 1 commit into main from dev
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
262 changes: 201 additions & 61 deletions solution/0300-0399/0311.Sparse Matrix Multiplication/README.md
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -42,43 +42,58 @@

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

**方法一:直接相乘**

我们可以直接按照矩阵乘法的定义,计算出结果矩阵中的每一个元素。

时间复杂度 $O(m \times n \times k),ドル空间复杂度 $O(m \times n)$。

**方法二:预处理**

我们可以预处理出两个矩阵的稀疏表示,即 $g1[i]$ 表示矩阵 $mat1$ 第 $i$ 行中所有非零元素的列下标和值,而 $g2[i]$ 表示矩阵 $mat2$ 第 $i$ 行中所有非零元素的列下标和值。

接下来,我们遍历每一行 $i,ドル遍历 $g1[i]$ 中的每一个元素 $(k, x),ドル遍历 $g2[k]$ 中的每一个元素 $(j, y),ドル那么最终 $mat1[i][k] \times mat2[k][j]$ 就会对应到结果矩阵中的 $ans[i][j],ドル我们将所有的结果累加即可。

时间复杂度 $O(m \times n \times k),ドル空间复杂度 $O(m \times n)$。

<!-- tabs:start -->

### **Python3**

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

直接模拟。

```python
class Solution:
def multiply(self, mat1: List[List[int]], mat2: List[List[int]]) -> List[List[int]]:
r1, c1, c2 = len(mat1), len(mat1[0]), len(mat2[0])
res = [[0] * c2 for _ in range(r1)]
for i in range(r1):
for j in range(c2):
for k in range(c1):
res[i][j] += mat1[i][k] * mat2[k][j]
return res
m, n = len(mat1), len(mat2[0])
ans = [[0] * n for _ in range(m)]
for i in range(m):
for j in range(n):
for k in range(len(mat2)):
ans[i][j] += mat1[i][k] * mat2[k][j]
return ans
```

用哈希表记录稀疏矩阵 mat1 中的非 0 值。

```python
class Solution:
def multiply(self, mat1: List[List[int]], mat2: List[List[int]]) -> List[List[int]]:
r1, c1, c2 = len(mat1), len(mat1[0]), len(mat2[0])
res = [[0] * c2 for _ in range(r1)]
mp = defaultdict(list)
for i in range(r1):
for j in range(c1):
if mat1[i][j] != 0:
mp[i].append(j)
for i in range(r1):
for j in range(c2):
for k in mp[i]:
res[i][j] += mat1[i][k] * mat2[k][j]
return res
def f(mat: List[List[int]]) -> List[List[int]]:
g = [[] for _ in range(len(mat))]
for i, row in enumerate(mat):
for j, x in enumerate(row):
if x:
g[i].append((j, x))
return g

g1 = f(mat1)
g2 = f(mat2)
m, n = len(mat1), len(mat2[0])
ans = [[0] * n for _ in range(m)]
for i in range(m):
for k, x in g1[i]:
for j, y in g2[k]:
ans[i][j] += x * y
return ans
```

### **Java**
Expand All @@ -88,26 +103,51 @@ class Solution:
```java
class Solution {
public int[][] multiply(int[][] mat1, int[][] mat2) {
int r1 = mat1.length, c1 = mat1[0].length, c2 = mat2[0].length;
int[][] res = new int[r1][c2];
Map<Integer, List<Integer>> mp = new HashMap<>();
for (int i = 0; i < r1; ++i) {
for (int j = 0; j < c1; ++j) {
if (mat1[i][j] != 0) {
mp.computeIfAbsent(i, k -> new ArrayList<>()).add(j);
int m = mat1.length, n = mat2[0].length;
int[][] ans = new int[m][n];
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < mat2.length; ++k) {
ans[i][j] += mat1[i][k] * mat2[k][j];
}
}
}
for (int i = 0; i < r1; ++i) {
for (int j = 0; j < c2; ++j) {
if (mp.containsKey(i)) {
for (int k : mp.get(i)) {
res[i][j] += mat1[i][k] * mat2[k][j];
}
return ans;
}
}
```

```java
class Solution {
public int[][] multiply(int[][] mat1, int[][] mat2) {
int m = mat1.length, n = mat2[0].length;
int[][] ans = new int[m][n];
var g1 = f(mat1);
var g2 = f(mat2);
for (int i = 0; i < m; ++i) {
for (int[] p : g1[i]) {
int k = p[0], x = p[1];
for (int[] q : g2[k]) {
int j = q[0], y = q[1];
ans[i][j] += x * y;
}
}
}
return res;
return ans;
}

private List<int[]>[] f(int[][] mat) {
int m = mat.length, n = mat[0].length;
List<int[]>[] g = new List[m];
Arrays.setAll(g, i -> new ArrayList<>());
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (mat[i][j] != 0) {
g[i].add(new int[] {j, mat[i][j]});
}
}
}
return g;
}
}
```
Expand All @@ -118,20 +158,48 @@ class Solution {
class Solution {
public:
vector<vector<int>> multiply(vector<vector<int>>& mat1, vector<vector<int>>& mat2) {
int r1 = mat1.size(), c1 = mat1[0].size(), c2 = mat2[0].size();
vector<vector<int>> res(r1, vector<int>(c2));
unordered_map<int, vector<int>> mp;
for (int i = 0; i < r1; ++i) {
for (int j = 0; j < c1; ++j) {
if (mat1[i][j] != 0) mp[i].push_back(j);
int m = mat1.size(), n = mat2[0].size();
vector<vector<int>> ans(m, vector<int>(n));
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
for (int k = 0; k < mat2.size(); ++k) {
ans[i][j] += mat1[i][k] * mat2[k][j];
}
}
}
for (int i = 0; i < r1; ++i) {
for (int j = 0; j < c2; ++j) {
for (int k : mp[i]) res[i][j] += mat1[i][k] * mat2[k][j];
return ans;
}
};
```

```cpp
class Solution {
public:
vector<vector<int>> multiply(vector<vector<int>>& mat1, vector<vector<int>>& mat2) {
int m = mat1.size(), n = mat2[0].size();
vector<vector<int>> ans(m, vector<int>(n));
auto g1 = f(mat1), g2 = f(mat2);
for (int i = 0; i < m; ++i) {
for (auto& [k, x] : g1[i]) {
for (auto& [j, y] : g2[k]) {
ans[i][j] += x * y;
}
}
}
return res;
return ans;
}

vector<vector<pair<int, int>>> f(vector<vector<int>>& mat) {
int m = mat.size(), n = mat[0].size();
vector<vector<pair<int, int>>> g(m);
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
if (mat[i][j]) {
g[i].emplace_back(j, mat[i][j]);
}
}
}
return g;
}
};
```
Expand All @@ -140,27 +208,99 @@ public:

```go
func multiply(mat1 [][]int, mat2 [][]int) [][]int {
r1, c1, c2 := len(mat1), len(mat1[0]), len(mat2[0])
res := make([][]int, r1)
for i := range res {
res[i] = make([]int, c2)
m, n := len(mat1), len(mat2[0])
ans := make([][]int, m)
for i := range ans {
ans[i] = make([]int, n)
}
mp := make(map[int][]int)
for i := 0; i < r1; i++ {
for j := 0; j < c1; j++ {
if mat1[i][j] != 0 {
mp[i] = append(mp[i], j)
for i := 0; i < m; i++ {
for j := 0; j < n; j++ {
for k := 0; k < len(mat2); k++ {
ans[i][j] += mat1[i][k] * mat2[k][j]
}
}
}
for i := 0; i < r1; i++ {
for j := 0; j < c2; j++ {
for _, k := range mp[i] {
res[i][j] += mat1[i][k] * mat2[k][j]
return ans
}
```

```go
func multiply(mat1 [][]int, mat2 [][]int) [][]int {
m, n := len(mat1), len(mat2[0])
ans := make([][]int, m)
for i := range ans {
ans[i] = make([]int, n)
}
f := func(mat [][]int) [][][2]int {
m, n := len(mat), len(mat[0])
g := make([][][2]int, m)
for i := range g {
g[i] = make([][2]int, 0, n)
for j := range mat[i] {
if mat[i][j] != 0 {
g[i] = append(g[i], [2]int{j, mat[i][j]})
}
}
}
return g
}
return res
g1, g2 := f(mat1), f(mat2)
for i := range g1 {
for _, p := range g1[i] {
k, x := p[0], p[1]
for _, q := range g2[k] {
j, y := q[0], q[1]
ans[i][j] += x * y
}
}
}
return ans
}
```

### **TypeScript**

```ts
function multiply(mat1: number[][], mat2: number[][]): number[][] {
const [m, n] = [mat1.length, mat2[0].length];
const ans: number[][] = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
for (let k = 0; k < mat2.length; ++k) {
ans[i][j] += mat1[i][k] * mat2[k][j];
}
}
}
return ans;
}
```

```ts
function multiply(mat1: number[][], mat2: number[][]): number[][] {
const [m, n] = [mat1.length, mat2[0].length];
const ans: number[][] = Array.from({ length: m }, () => Array.from({ length: n }, () => 0));
const f = (mat: number[][]): number[][][] => {
const [m, n] = [mat.length, mat[0].length];
const ans: number[][][] = Array.from({ length: m }, () => []);
for (let i = 0; i < m; ++i) {
for (let j = 0; j < n; ++j) {
if (mat[i][j] !== 0) {
ans[i].push([j, mat[i][j]]);
}
}
}
return ans;
};
const g1 = f(mat1);
const g2 = f(mat2);
for (let i = 0; i < m; ++i) {
for (const [k, x] of g1[i]) {
for (const [j, y] of g2[k]) {
ans[i][j] += x * y;
}
}
}
return ans;
}
```

Expand Down
Loading

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