1. 程式人生 > >O(logN)時間複雜度內求整數的N次方以及矩陣的N次方

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;
  }