题目
实现函数 double Power(double base,int
exponent),求base的exponent次方。不使用库函数,同时不需要考虑大数问题,exponent是32位有符号整数。示例一
输入:2.0,10
输出:1024.00000
示例二
输入:2.0 ,-2
输出:0.250000
算法思路
分析此题,几个关键条件,一是base的类型是double,二是不得使用库函数,次方n为无符号整数,n可能为负数。
方法一 递归
很明显,本题可以通过不断往下递归,每次递归将n除以2,具体步骤如下:
- 递归参数:就在原函数的基础上进行递归,即参数还是base和n,只是每次递归时,base和n都变化了;
- 递归终止条件:当n为0时,不在继续向下递归,返回1(任何数的0次方都是1);
- 递归过程:每次向下递归的参数base 等于本次base的平方,即x = x*x,同时n右移一位,即n除以2,当n不能够被2整除时,还需在递归的基础上乘以base;
根据指数是奇数还是偶数进行分类讨论,使用位运算的 与 运算符代替了求余数运算。
方法二:快速幂法(迭代)
在不使用递归时,可以通过迭代方式。
算法流程:
- 当 x = 0 时:直接返回 0 (避免后续 x = 1 / x 操作报错)。
- 初始化 res = 1 ;
- 当 n < 0时:把问题转化至 n≥0 的范围内,即执行 x = 1/x,n = - n;
- 循环计算:当 n = 0 时跳出;当 n & 1 = 1 时:将当前 x乘入 res(即 res *= x);执行 x = x^2(即 x *= x );执行 n 右移一位(即 n >>= 1);
- 返回 res 。
代码
class Solution {
/***************** 递归 ********************/
public double myPow(double x, int n) {
if(n == 0) return 1;
if(n == -1) return 1.0/x;
if((n&1) == 1) return myPow(x*x,n>>1)*x;
return myPow(x*x,n>>1);
}
/***************** 迭代 ********************/
public double myPow1(double x, int n) {
if(x == 0) return 0;
double res = 1.0;
long b = n;
if(b < 0){
x = 1.0/x;
b = -b;
}
while(b != 0){
if((b&1) == 1) res *= x;
x *= x;
b >>= 1;
}
return res;
}
}
复杂度
其实两种方法都可以看做二分法的变形,所以时间复杂度为 O(logN),空间复杂度 O(1)。
注意点
要注意的一点是,虽然题目中告诉我们不需要考虑大数问题,但是给出的 n 可以取到 -2147483648−2147483648(整型负数的最小值),因此,在编码的时候,需要将 n 转换成 long 类型。
本文深入解析快速幂算法,包括递归和迭代两种实现方式,详细阐述了如何在不使用库函数的情况下,高效计算base的exponent次方。适用于32位有符号整数的指数计算。
385

被折叠的 条评论
为什么被折叠?



