3种算法 - 利用历史数据实现幂函数

解法一

思路:直接暴力法x求积,n很大时肯定会超时,那么使用多重幂次进行减少运算,即,使用上一次的幂次运算的结果,执行步骤和代码如下:(实现思路跟【2种解法:实现两数相除】完全一样)

  1. 将幂次分解: n = 2 a + 2 b + 2 c + . . . + 1 n = 2^a + 2^b + 2^c +...+ 1 n=2a+2b+2c+...+1

  2. 幂次递归: ( x ) n = ( x ) 2 a + 2 b + 2 c + . . . + 1 = ( x ) 2 a ∗ ( x ) 2 b ∗ ( x ) 2 c ∗ . . . ∗ x (x)^n = (x)^{ 2^a + 2^b + 2^c +...+ 1} = (x)^{ 2^a} * (x)^{ 2^b} * (x)^{ 2^c} * ... * x (x)n=(x)2a+2b+2c+...+1=(x)2a(x)2b(x)2c...x

  3. 单次递归的循环: ( x ) 2 a = ( ( ( ( ( ( ( ( x ) 2 ) 2 ) 2 ) 2 ) 2 ) 2 ) . . . ) 2 (x)^{ 2^a} = ((((((((x)^2)^2)^2)^2)^2)^2)...)^2 (x)2a=((((((((x)2)2)2)2)2)2)...)2,共嵌套a层

public class Solution {
    public double search(double x,int n)
    {
        if(n == 1) return x;
        if(n == 0) return 1;
        int t = 1;
        double r = x;
        while(n - t >= t)
        {//使用幂次运算
            t <<= 1;
            r *= r;
        }
        return r * search(x,n - t);
    }
    public double MyPow(double x, int n) {
        double nx = 1;
        if(n == int.MinValue)
        {//防止负值转化为正值时越界
            n = n+1;
            nx = x;
        }
        int  flag = n > 0?1:-1;
        int un = flag * n;
        double r = search(x,un) * nx;
        if(flag < 0)
        {//负值时候求导
            r = 1/r;
        }
        return r;
    }
}

在这里插入图片描述

解法二

思路:基于解法一的优化,优化有下面3点,代码如下:

  1. 不关心n的正负,只是用其值本身,使用0来判断结束条件
  2. 利用每次计算的幂次结果,而不用每次在递归中从头开始计算
  3. 使用最低位跟1的与运算,来代替求余运算,减少负数求余后再求绝对值
public class Solution {
    public double MyPow(double x, int n) {
        bool  flag = n > 0?true:false;
        double r = 1;
        while(n != 0)
        {
            if((n & 1) == 1)
            {//最后一次(n==1)一定会进来
                r *= x;
            }
            x *= x;
            n /= 2;
        }
        return flag?r:(1/r);
    }
}

在这里插入图片描述

解法三

思路:基于解法二,使用递归代替循环来实现,看起来更简洁,代码如下:

public class Solution {
    public double MyPow(double x, int n) {
        if(n == 0) return 1;
        if(n == 1) return x;
        if(n == -1) return 1/x;

        double r = MyPow(x,n/2);
        double t = MyPow(x,n%2);

        return  r * r *t;
    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放羊郎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值