16. 数值的整数次方

剑指offer 16 数值的整数次方

50. Pow(x, n)

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

示例 1:

输入: 2.00000, 10
输出: 1024.00000

示例 2:

输入: 2.10000, 3
输出: 9.26100

示例 3:

输入: 2.00000, -2
输出: 0.25000
解释: 2 − 2 = 1 / 2 2 = 1 / 4 = 0.25 2^{-2} = 1/2^2 = 1/4 = 0.25 22=1/22=1/4=0.25

说明:

-100.0 < x < 100.0
n32 位有符号整数,其数值范围是 [ − 2 31 , 2 31 − 1 −2^{31}, 2^{31} − 1 231,2311] 。

注意:本题与主站 50 题相同:https://leetcode-cn.com/problems/powx-n/

解法一:暴力解法

解法一:暴力解法(不推荐,效率太低,太low了),即先判断exponent正负,取绝对值后,让base乘以自身exponent次即可,最后根据开始exponent的正负情况返回1/res或者res

解法二:分治思想

分治思想,因为乘法是可交换的,所以可以将上述操作拆开成两半(x * x..x) (x * x..x),两半的计算是一样的,因此只需要计算一次。而且对于新拆开的计算,又可以继续拆开。这就是分治思想,将原问题的规模拆成多个规模较小的子问题,最后子问题的解合并起来,时间复杂度变为 O ( l o g n ) O(logn) O(logn)

n8时的分治过程如图:
在这里插入图片描述

本题中合并时将子问题的解乘以自身即可。但如果 n 不为偶数,那么拆成两半还会剩下一个 x,此时再将子问题合并时还需要多乘一个 x

x n = { x n 2 ∗ x n 2 n   m o d   2 = 0 x ∗ ( x n 2 ∗ x n 2 ) n   m o d   2 = 1 x^n=\left\{ \begin{aligned} x^\frac{n}{2} * x^\frac{n}{2} && n\bmod2=0 \\ x*(x^\frac{n}{2} * x^\frac{n}{2}) && n\bmod2=1 \end{aligned} \right. xn={x2nx2nx(x2nx2n)nmod2=0nmod2=1

Java代码
class Solution {
    public double myPow(double x, int n) {
        /*主要是要考虑指数为负数时结果要取倒数
        然后分奇偶使用递归将计算将过程减半*/
        double res = 1;
        int num = Math.abs(n);
        if(n > 0){
            return pow(x,num);
        }else{
            return 1/pow(x,num);
        }
    }
   public double pow(double x,int n){
       if(n == 0){
           return 1;
       }
       //分治(类似归并排序中的左右mergeSort,只是这里左右两边一样,故只要写一个)
       double y = pow(x,n/2);
       
       //合并(类似归并排序中的merge阶段)
       if(n % 2 == 0){
          return y*y;
       }else{
           return y*y*x;
       }
   } 
}

在这里插入图片描述

Go代码

func myPow(x float64, n int) float64 {
    /*主要是要考虑指数为负数时结果要取倒数
    然后分奇偶使用递归将计算将过程减半*/
    flag := false
    if n < 0 {
        flag = true
        n = -n
    }
    res := pow(x,n)

    if flag {
        return 1 / res
    }

    return res
}

func pow(x float64,n int) float64 {
    if n == 0 {
        return 1
    }

    y := pow(x,n/2)

    if n % 2 == 0 {
        return y * y
    } else {
        return x*y*y
    }
}

解法三:快速幂

快速幂的介绍可以参考本人博客day27 89 a^b (快速幂)

Java代码
class Solution {
    public double myPow(double x, int n) {
        //快速幂解法
        double res = 1;
        boolean flag = n < 0;
        n = Math.abs(n);
        while(n != 0){
           if((n & 1) != 0) res *= x;
            x *= x;
            n >>= 1;
        }
        if(flag){
            return 1 / res;
        }
        return res;
   } 
}

n为负无穷时,取绝对值会超出int范围,即使转成long也会出现如下报错。但这里还是将代码贴出来了,因为思路是完全正确的,就当复习一下快速幂吧。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值