*leetcode刷题_day8_(math,int,递归)剑指offer11(数值的整数次方)

剑指offer11 实现power方法,不使用库函数:

也就是说求 a**b,不直接使用power方法。

解答:

  1. 最简单的循环相乘法,临界条件:累计乘b次得到结果
  2. 边界条件:base=0时,输出全为0;exp为0时,输出全为1(对于0**0无意义,可以单独得到结果,解释即可);exp为正时,正常;exp为负时,结果为1/res。

代码:省略。
tips:
可能遇到超时问题,一步步相乘时,过程不够高效,可以进行优化。
考虑,对于极大的b,先得到a ^2 ,然后 a ^4,接着a ^8…这样类似于二分法的方法极大地降低了时间复杂度。
等式表示:
a^b = a ^(b/2) * a ^(b/2) b为偶数
= a^((b-1)/2) * a^((b-1)/2) * a b为奇数
这里可以使用递归了。因为递归是从大往小分(实际输出是先小后大),所以不用担心结果在a ^15次方这样卡在8和16的情况时是否需要返回上一步的做法(15变为7,7变为3,3变为1,为奇数的时候注意要在得到的结果再进行一次乘base)。

新的解答:

  1. 边界条件:base=0时,直接回0
  2. else 里面 将 base与exp全化为非负数处理。sign1默认为1 表示exp正,然后判断 exp如果<0,则将其变为-1(最后的结果再判定1/res); base变为正数,同时sign2代表其正负。
  3. 进入下一步,exp的边界分析:exp为0时直接返回1,exp为1时返回base(适用于递归以及常规情况)
  4. 下一步,exp的常规情况:进入递归,exp>>1表示取模的效果,得到之前的值后,res*res,这里表示exp模2的同时,res自己相乘(倒过来看就是上个递归的res自乘,同时exp乘2)。
  5. 此处注意对每次的exp进行奇数的判断,如果时则还需要乘以自身
  6. 最后,根据sign1和sign2进行最后结果的输出(同样适用于递归时,因为递归时都是正数,状态均为1)。
    代码:
def myPower(base,exp):
    if base ==0:
        return 0
    else:
        base,sign2 = abs(base), base/abs(base)
        sign1 = 1

        if exp<0:
            sign1 = -1
            exp = abs(exp)
        if exp == 0:
            return 1
        elif exp ==1:
            return base
        else:
            res = myPower(base,exp>>1)
            print(res)
            res = res*res
        if exp%2==1:
            res = res*base

        if sign2 == -1:
            res = -res

        if sign1 == -1:
            res = 1/res
        return res
    #return res if sign1>0 else 1/res
base1,base2,base3,base4 = 0,-3,5,18
exp1,exp2,exp3,exp4 = 0,-3,4,30

print(myPower(base3,exp4),5**(30))
#print(myPower(-3,3),-3**3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值