题意整理:

本题题意非常清晰,就是求出两个矩阵的矩阵乘积
对于两个矩阵,设 的矩阵, 的矩阵,那么它们的乘积结果为一个 的矩阵 。其中, 的第 行第 列的元素计算方法如下
需要注意的是,只有矩阵的列数和矩阵的行数相同的时候,两个矩阵才能进行乘法
对于本题,给定的两个矩阵维数相同,所以无需判断。

方法一:暴力模拟

核心思想:

直接根据上述公式,进行模拟后计算即可。具体实现为枚举矩阵 的行以及矩阵 的列,第三维的 枚举上述公式的 1 到 p 进行计算即可。

核心代码:

class Solution {
public:
    vector<vector<int> > solve(vector<vector<int> >& a, vector<vector<int> >& b) {
        int n = a.size();
        vector<vector<int>> ans(n, vector<int>(n)); //用于存储结果
        for(int i = 0; i < n; i++)
            for(int j = 0; j < n; j++)
                for(int k = 0; k < n; k++) {
                    ans[i][j] += a[i][k] * b[k][j]; //行*列相加
                }
         return ans;
    }
};

复杂度分析:

时间复杂度:,使用了三重循环,枚举行列以及对单个元素进行计算。
空间复杂度:,不计算答案数组,使用的空间为常数个遍历

方法二:暴力法的优化

核心思想:

此优化需要一些对操作系统的知识。
二维矩阵实际上是转换为一维形式存储的。如下图
图片说明
而对于CPU的数据读取,对连续数据的读取的效率的高于跳跃性的读取的。在方法一中,对单个元素 的计算中,需要跳跃性的对矩阵 进行访问,这会使得效率下降。我们可以通过调整枚举的顺序进行优化,使得两个矩阵的读取都为顺序读取。虽然时间复杂度不变,但基于CPU的连续读取特性,实际运行效率会比方法一高。

核心代码:

class Solution {
public:
    vector<vector<int> > solve(vector<vector<int> >& a, vector<vector<int> >& b) {
        int n = a.size();
        int res;
        vector<vector<int> > ans(n, vector<int>(n)); //用于存储结果
        for(int i = 0; i < n; i++)
            for(int k = 0; k < n; k++){
                res = a[i][k];
                for(int j = 0; j < n; j++) {
                    ans[i][j] += res * b[k][j]; //行*列相加
                }
            }
         return ans;
    }
};

复杂度分析:

时间复杂度:,使用了三重循环,枚举行列以及对单个元素进行计算。虽然时间复杂度不变,但对于较大矩阵,本方法比方法一要快很多。
空间复杂度:,不计算答案数组,使用的空间为常数个遍历