leetcode:311. 稀疏矩阵的乘法(会员题)
lintcode:654 · 稀疏矩阵乘法
题目
给定两个 稀疏矩阵 A 和 B,返回 AB 的结果。
您可以假设 A 的列数等于 B 的行数。
示例:
输入:[[1,0,0],[-1,0,3]][[7,0,0],[0,0,0],[0,0,1]]输出:[[7,0,0],[-7,0,3]]解释:A = [[ 1, 0, 0],[-1, 0, 3]]B = [[ 7, 0, 0 ],[ 0, 0, 0 ],[ 0, 0, 1 ]]| 1 0 0 | | 7 0 0 | | 7 0 0 |AB = | -1 0 3 | x | 0 0 0 | = | -7 0 3 || 0 0 1 |
输入:[[1,0],[0,1]][[0,1],[1,0]]输出:[[0,1],[1,0]]
解答 & 代码
解法一:模拟(暴力,三重循环)
class Solution {public:/*** @param a: a sparse matrix* @param b: a sparse matrix* @return: the result of A * B*/vector<vector<int>> multiply(vector<vector<int>> &a, vector<vector<int>> &b) {int rows = a.size(); // 结果矩阵的行数(a 矩阵的行数)int cols = b[0].size(); // 结果矩阵的列数(b 矩阵的列数)int dim = a[0].size(); // 中间维度(a 矩阵的列数、b 矩阵的行数)vector<vector<int>> result(rows, vector<int>(cols, 0)); // 结果矩阵// 三重循环for(int i = 0; i < rows; ++i){for(int j = 0; j < cols; ++j){// 计算 result[i][j],等于 a 矩阵第 i 行和 b 矩阵第 j 列对应元素相乘再求和for(int k = 0; k < dim; ++k)result[i][j] += a[i][k] * b[k][j];}}return result;}};
复杂度分析:设 a 矩阵 rows 行 dim 列,b 矩阵 dim 行 cols 列
- 时间复杂度 O(rows cols dim):
- 空间复杂度 O(1):结果矩阵的空间复杂度不计入
执行结果:
执行结果:通过执行用时:61 ms, 在所有 C++ 提交中击败了 57.80% 的用户内存消耗:5.41 MB, 在所有 C++ 提交中击败了 57.80% 的用户
解法二:哈希表存储稀疏矩阵
class Solution {private:// 用哈希表存储稀疏矩阵matrix的非零元素,key = 行号,val = 哈希表(key=列号,val=非零元素值)unordered_map<int, unordered_map<int, int>> saveSparseMatrix(vector<vector<int>> &matrix, int rows, int cols){unordered_map<int, unordered_map<int, int>> hashMap;for(int i = 0; i < rows; ++i){unordered_map<int, int> rowMap;for(int j = 0; j < cols; ++j){if(matrix[i][j] != 0) // 哈希表中只存储非零元素rowMap[j] = matrix[i][j];}hashMap[i] = rowMap;}return hashMap;}public:/*** @param a: a sparse matrix* @param b: a sparse matrix* @return: the result of A * B*/vector<vector<int>> multiply(vector<vector<int>> &a, vector<vector<int>> &b) {int M = a.size(); // 结果矩阵的行数(a 矩阵的行数)int K = a[0].size(); // 结果矩阵的列数(b 矩阵的列数)int N = b[0].size(); // 中间维度(a 矩阵的列数、b 矩阵的行数)vector<vector<int>> result(M, vector<int>(N, 0)); // 结果矩阵// 分别用哈希表存储矩阵 a、矩阵 b 的非零元素unordered_map<int, unordered_map<int, int>> aMap = saveSparseMatrix(a, M, K);unordered_map<int, unordered_map<int, int>> bMap = saveSparseMatrix(b, K, N);for(int i = 0; i < M; ++i){unordered_map<int, int> aiMap = aMap[i];// 遍历矩阵 a 的每个非零元素 aik(第 i 行第 k 列个元素)for(auto itA = aiMap.begin(); itA != aiMap.end(); ++itA){int k = itA->first;int aik = itA->second;unordered_map<int, int> bkMap = bMap[k];// 遍历矩阵 b 的第 k 行非零元素 bkj// 因为矩阵 a 的第 k 列元素会和矩阵 b 第 k 行的每个元素相乘,加到 result[i][j]for(auto itB = bkMap.begin(); itB != bkMap.end(); ++itB){int j = itB->first;int bkj = itB->second;result[i][j] += aik * bkj;}}}return result;}};
执行结果:
执行结果:通过执行用时:41 ms, 在所有 C++ 提交中击败了 98.40% 的用户内存消耗:4.58 MB, 在所有 C++ 提交中击败了 98.40% 的用户
