显然是求斐波那契数列的函数,1、1、2、3、5、8、13、21、34、……
首先想到的是递归:
public static int F(int number){
if (number == 1 || number == 2){
return 1;
}
return F(number - 1) + F(number - 2);
}
但是,最好不用递归,不到万不得已不用递归。
上面一段代码性能极差,当给定参数number=100时,已经循环不动。
=================================================================================
……………………①
………………②
于是只要求得即可。
=================================================================================
而类似求还可以简化(快速幂)
例如:
时间复杂度是n=19
时间复杂度n=5,平方后的数都可以看做是整体,全部下来只需做5次乘法。
求的伪代码如下:
初始化res = X,tmp = 1,n = 19(二进制10011)
(1)判断 n & 1 (按位与,值为1,得出n为奇数)
tmp = tmp * res = 1 * X = X
res = res * res = X * X =
n = n >> 1 (二进制1001,n向右移动一位,相当于除以2)
(2)判断 n & 1 (值为1)
tmp = tmp * res = 1 * =
res = res * res =
n = n >> 1 (二进制100)
(3)判断 n & 1 (值为0,得出n为偶数)
res = res * res =
n = n >> 1 (二进制10)
(4)判断 n & 1 (值为0,得出n为偶数)
res = res * res =
n = n >> 1 (二进制1)
(5)判断 n & 1 (值为1,得出n为奇数数)
tmp = tmp * res =
res = res * res =
return tmp
=================================================================================
Java代码实现如下:
//定义两个矩阵相乘
//防止结果溢出,使用BigInteger类型
public static BigInteger[][] matrixProduct(BigInteger[][] arrLeft, BigInteger[][] arrRight){
BigInteger result[][] = {{new BigInteger("0"),new BigInteger("0")},{new BigInteger("0"),new BigInteger("0")}};
for (int i = 0; i <= 1; i++){
for (int j = 0; j <= 1; j++){
result[i][j] = arrLeft[i][0].multiply(arrRight[0][j]).add(arrLeft[i][1].multiply(arrRight[1][j]));
}
}
return result;
}
//定义矩阵的平方
public static BigInteger[][] matrixProductSquare(BigInteger [][] arrIn){
BigInteger result[][] = {{new BigInteger("0"),new BigInteger("0")},{new BigInteger("0"),new BigInteger("0")}};
BigInteger [][] arrLeft = arrIn;
BigInteger [][] arrRight = arrIn;
if (arrIn != null){
for (int i = 0; i <= 1; i++){
for (int j = 0; j <= 1; j++){
result[i][j] = arrLeft[i][0].multiply(arrRight[0][j]).add(arrLeft[i][1].multiply(arrRight[1][j]));
}
}
}
//定义矩阵快速幂方法
public static BigInteger[][] matrixFastPower(BigInteger[][] arrIn, int n){
BigInteger result[][] = arrIn;
BigInteger tmp[][] = {{new BigInteger("1"),new BigInteger("0")},{new BigInteger("0"),new BigInteger("1")}};//初始值为单位阵
while (n != 0){
if ((n & 1) == 1){
tmp = matrixProduct(tmp.clone(), result);//参与计算的矩阵又赋值给原来的矩阵,需要深拷贝
result = matrixProductSquare(result.clone());
n = n >> 1;
}else {
result = matrixProductSquare(result.clone());
n = n>>1;
}
}
return tmp;
}
//经测试,100万次方需要3秒钟,1000万次方需要58秒钟
public static void main(String[] args) {
long start = System.currentTimeMillis();
BigInteger arrIn[][] = {{new BigInteger("1"),new BigInteger("1")},{new BigInteger("1"),new BigInteger("0")}};
BigInteger res[][] = matrixFastPower(arrIn, 10000000);
for (int i = 0; i <= 1; i++){
for (int j = 0; j <= 1; j++){
System.out.println(res[i][j].toString());
}
}
System.out.println((System.currentTimeMillis() - start) / 1000);
}
f(10000000)运行结果如下(打印也要耗费时间)。