实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

示例 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 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。

直接考虑

首先想到的是循环遍历。但是不出所料,超出时长。。

class Solution {
    public double myPow(double x, int n) {
        double sum=1;
        if(n>=0){
             for(int i=0;i<n;i++){
                sum=sum*x;
            }
        }
        else{
            for(int i=0;i>n;i--){
                sum=sum/x;
            }  
        }
        return sum;
    }
}

快速幂运算

求 x^n 最简单的方法是通过循环将 n 个 x 乘起来,依次求 x^1, x^2, …, x^{n-1} ,时间复杂度为 O(n)。
快速幂法 可将时间复杂度降低至 O(log_2 n) ,以下从 “二分法” 和 “二进制” 两个角度解析快速幂法。

大神的数学推导,学不来。

算法流程:

1. 当 x = 0 时:直接返回 0(避免后续 x = 1 / xx=1/x 操作报错)。
2. 初始化 res = 1 ;
3. 当n<0 时:把问题转化至 n≥0 的范围内,即执行 x = 1/x=1/x ,n = - n ;
4. 循环计算:当 n=0 时跳出;
	4.1. 当n&1=1 时:
	4.2. 将当前 x 乘入 res(即res∗=x );
	4.3. 执行 x = x^2(即 x∗=x );
	4.4. 执行 n 右移一位(即 n >>= 1)。
5. 返回 res 。

Java 代码中 int32 变量 n∈[−2147483648,2147483647] ,因此当 n = -2147483648时执行 n = -n会因越界而赋值出错。解决方法是先将 n 存入 long 变量 b ,后面用 b操作即可。

class Solution {
    public double myPow(double x, int n) {
        if(x == 0) return 0;
        long b = n;
        double res = 1.0;
        if(b < 0) {
            x = 1 / x;
            b = -b;
        }
        while(b > 0) {
            if((b & 1) == 1) res *= x;
            x *= x;
            b >>= 1;
        }
        return res;
    }
}

复杂度分析:
时间复杂度 O(log2 n)二分的时间复杂度为对数级别。
空间复杂度 O(1 ): res, b 等变量占用常数大小额外空间。