O(logN)时间复杂度内求整数的N次方以及矩阵的N次方

整数N次方

假设一个整数是10,如何最快地求解10的75次方。
1. 75的二进制数形式为1001011
2. 10的75次方=10^64 × 10^8 × 10^2 × 10^1

在这个过程中,我们先求出10^1,然后根据10^2,再根据10^2求出10^4,……,最后根据10^32求出10^64,即75的二进制数形式总共为多少位,我们就要在原基础上平方几次。

  1. 在步骤2进行的过程中,只有遇到位为1时,才将结果累乘当前的平方数。比如,10^64、10^8、10^2、10^1应该累乘。
  /**
   * 巧算
   */
  static int ex2(int n, int m) {
    int pingFangShu = n; //n 的 1 次方
    int result = 1;
    while (m != 0) {
      //遇1累乘现在的幂
      if ((m & 1) != 0)
        result *= pingFangShu;
      //每移位一次,幂累乘方一次
      pingFangShu = pingFangShu * pingFangShu;
      //右移一位
      m >>= 1;
    }
    return result;
  }

矩阵乘法

  /**
   *   矩阵乘法
   *   矩阵1为n*m矩阵,矩阵2为m*p矩阵
   *   结果为n*p矩阵
   */
  public static long[][] matrixMultiply(long[][] m1, long[][] m2) {
    final int n = m1.length;
    final int m = m1[0].length;
    final int p = m2[0].length;

    long[][] result = new long[n][p];// 新矩阵的行数为m1的行数,列数为m2的列数
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < p; j++) {
        for (int k = 0; k < m; k++) {
          result[i][j] += m1[i][k] * m2[k][j];
        }
      }
    }
    return result;
  }

矩阵的N次方

求矩阵的N次方,思路和求整数的N次方接近,区别是矩阵乘法和整数乘法在细节上不一样,但对于怎么乘更快,原理上是一致的。

  /**
   * 求矩阵matrix的p次方
   * @param matrix
   * @param p
   * @return
   */
  public static long[][] matrixPower(long[][] matrix, int p) {
    //初始化结果为单位矩阵,对角线为1
    long[][] result = new long[matrix.length][matrix[0].length];
    //单位矩阵,相当于整数的1
    for (int i = 0; i < result.length; i++) {
      result[i][i] = 1;
    }

    //平方数
    long[][] pingFang = matrix; // 一次方
    for (; p != 0; p >>= 1) {
      if ((p & 1) != 0) { // 当前二进制位最低位为1,将当前平方数乘到结果中
        result = matrixMultiply(result, pingFang);
      }
      //平方数继续上翻
      pingFang = matrixMultiply(pingFang, pingFang);
    }
    return result;
  }
发布了127 篇原创文章 · 获赞 97 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/zhengwei223/article/details/78758775
今日推荐