O(logN)時間複雜度內求整數的N次方以及矩陣的N次方
阿新 • • 發佈:2019-02-04
整數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的二進位制數形式總共為多少位,我們就要在原基礎上平方几次。
- 在步驟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;
}