1. 问题描述:
有的时候我们需要计算出一个矩阵的n次幂,因为有的时候我们需要将问题转化为矩阵的n次幂之后那么可以降低时间的复杂度,但是希望不要通过循环一个矩阵乘以一个矩阵,因为这样的时间复杂度为O(n),希望能够通过较快的方法来计算出矩阵的n次幂,一种方法就是类似于求解一个数字的快速幂运算的方法来进行求解,其中还会涉及到矩阵的乘法的运算,而矩阵的能够相乘需要满足A矩阵的列要等于B矩阵的行,具体的计算的方法是使用A矩阵的行对应的数字乘以B矩阵的列对应数字然后把每一次相加得到结果矩阵中当前所在行与所在列的值
例如当求解一个矩阵的7次幂的时候,我们知道7对应的二进制数字为111,所以我们可以通过 2 ^ 4 * 2 ^ 2 * 2 ^ 1次方来进行求解,在循环中我们每一次都是求解出当前二进制位上对应的权重,假如当前的二进制位1那么就将之前矩阵计算的结果再乘以当前位上的权重,这样每一次都是以2的指数这样去增长,时间复杂度相当于lgn,这样就比之前的循环中一个矩阵一个矩阵累乘的方法的时间复杂度就要低
2. 具体的代码如下:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int matrix[][] = {
{1, 1},
{1, 1}
};
//计算上面的矩阵的n次幂
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
//采用的方法是循环检查n有多少个1
int res[][] = matrixPower(matrix, n);
for(int i = 0; i < res.length; i++){
for(int j = 0; j < res[0].length; j++){
System.out.print(res[i][j] + " ");
}
System.out.print("\n");
}
sc.close();
}
private static int[][] matrixPower(int[][] matrix, int n) {
int res[][] = new int[matrix.length][matrix.length];
int pingfang[][] = matrix;
for(int i = 0; i < matrix.length; i++){
res[i][i] = 1;
}
if(n == 0 || n == 1)return res;
while(n != 0){
if((n & 1) == 1){
res = matrixMultiple(res, pingfang);
}
pingfang = matrixMultiple(pingfang, pingfang);
//取出n中每一位上的1
n >>= 1;
}
return res;
}
private static int[][] matrixMultiple(int[][] matrixA, int[][] matrixB) {
//声明一个数组来记录矩阵的结果
int res[][] = new int[matrixA.length][matrixB[0].length];
//矩阵的乘法使用的是三重的for循环
for(int i = 0; i < matrixA.length; i++){
for(int j = 0; j < matrixB[0].length; j++){
int sum = 0;
for(int k = 0; k < matrixA[0].length; k++){
sum += matrixA[i][k] * matrixB[k][j];
}
res[i][j] = sum;
}
}
return res;
}
}