前言:今天做了一道题,可以用快速幂很好地实现,因为初次接触快速幂,刚开始比较懵圈,现在理解了一下,记录一下小白的心路历程。
————————
bui~~
快速幂
首先快速幂是什么呢,通俗来说,就是利用位运算实现一个数的 n 次幂
举例:以 a 的 10 次幂为例
如果通过连乘来求,则需要 10 次运算, 而通过快速幂,我们只需要运算 4 次,也就是二进制位数次的运算
但是这是怎么算的呢?其实我刚开始有些疑惑,这里说一下:
首先,要知道幂次的二进制有什么含义,从上面的例子可以看到
- 当二进制的当前位为 0 时,其 2 的 i 次幂与 0 相乘,结果为 0
- 当二进制的当前位为 1 时,其 2 的 i 次幂与 1 相乘
则我们只需要根据二进制, 就能够求出一个数的 n 次幂
即二进制的某位为 0 时,为a ^ 0 = 1;
二进制的某位为 1 时,a ^ (2 ^ j) ——>注意:这里的 j 与当前下标有关,即与二进制当前的位次有关
运算过程:
初始化 ans = 1 记录结果, 求 a 的 10 次幂
简单来说:
例:
a ^ 11
11 的二进制 : 1011
则 a ^ 11 = a ^ 1 * a ^ 2 * a ^ 0 * a ^ 8
a ^ 13
13的二进制 : 1101
则 a^ 13 = a ^ 1 * a ^ 0 * a ^ 4 * a ^ 8
————————————
bui~~
————————————
例题
题目链接: 50. Pow(x, n)
实现 pow(x, n) ,即计算 x 的 n 次幂函数。
例1:
输入: 2.00000, 10
输出: 1024.00000
例2:
输入: 2.10000, 3
输出: 9.26100
例3:
输入: 2.00000, -2
输出: 0.25000
解释: 2-2 = 1/22 = 1/4 = 0.25
说明:
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。
题目解析
根据幂次的二进制,通过 & 判断当前位值是 0 还是 1,然后参与运算
当为 1 时,ans 变化; 为 0 时, ans 不变
代码
class Solution {
public double myPow(double x, int n) {
int cur = n; //根据题意记录幂次的正负,决定最终结果
int res = 1; //记录最终值,并初始化为 1(不能为 0 , 会导致乘积始终为 0 )
while(n != 0){
if((n & 1) == 1){ //当前值为 1 时
ans *= x; //结果值改变,与 a ^ (2 ^ j)相乘
}
x *= x; //运算过程 x ^ 2, x ^ 4, x ^ 8 ……(即 :a ^ (2 ^ j)
n /= 2;//相当于 n >>= 1,但因为负数的>>2,会由于补码而一直在左边补 1 ,导致死循环
}
return cur >= 0 ? ans : 1 / ans; //判断结果返回最终结果
}
}
————————————
bui~~
突然收尾 (′▽`〃)
————————————