面试题16.数值的整数次方

本文深入解析快速幂算法,包括递归和迭代两种实现方式,详细阐述了如何在不使用库函数的情况下,高效计算base的exponent次方。适用于32位有符号整数的指数计算。

题目

实现函数 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 类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值