小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
题目
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,xn)。
示例 1:
输入: x = 2.00000, n = 10 输出: 1024.00000
示例 2:
输入: x = 2.10000, n = 3 输出: 9.26100
示例 3:
输入: x = 2.00000, n = -2 输出: 0.25000 解释: 2-2 = 1/22 = 1/4 = 0.25
提示:
-100.0 < x < 100.0-231 <= n <= 231-1-104 <= xn <= 104
思路
num: 传入的数字 ; power: 幂次
如果我们用循环将num自乘,乘power次,则时间复杂度是O(n)
我们可以利用:
numpower===(num∗num)power/2num^{power} === (num * num)^{power/2} numpower===(num∗num)power/2
- 如果是奇次幂,将power减1,转为偶数
numpower===num∗numpower−1num^{power}===num* num^{power-1} numpower===num∗numpower−1
- 不断将power二分,同时num值更新为num*num的值
- 循环直到power为1,终止
不断将幂次二分,减少了迭代次数,时间复杂度就变为O(logN)
- 注意power为负数的情况:
numpower===1num∗num−(power+1)num^{power} === \frac{1}{num*num^{-(power+1)}} numpower===num∗num−(power+1)1
- 因为最小的负数的绝对值比最大的正数大1,这么做防止数值溢出
方法1:迭代
- javascript
var myPow = function (num, power) {
if (power < 0) return 1 / num * myPow(1 / num, -(power + 1))
if (power === 0) return 1
if (power === 1) return num
// 以上分别为power小于0 等于0 等于1 的情况
let res = 1
while (power > 1) { // power大于1
if (power % 2 === 1) {
res = res * num
power--
}
num = num * num
power = power / 2
}
return res * num
};
总结
res 变量的值由奇次or偶次幂决定,如果是奇次幂,res 值为 num,反之,为1
res 最后乘上累乘后的 num,返回
方法2:递归
var myPow = (num, power) => {
if (power < 0) return 1 / (num * myPow(num, -(power + 1)))
if (power === 0) return 1
if (power === 1) return num
return power % 2 === 1 ?
num * myPow(num, power - 1) :
myPow(num * num, power / 2)
}
总结
递归版似乎更好理解一些,奇次幂的话,幂次-1,转成偶次幂
只需要写好偶次幂下的调用就好:myPow(num * num, power / 2)
最后
曾梦想仗剑走天涯
看一看世界的繁华
年少的心总有些轻狂
终究不过是个普通人
无怨无悔我走我路