「前端刷题」50. Pow(x, n)

253 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

题目

实现 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)

最后

曾梦想仗剑走天涯

看一看世界的繁华

年少的心总有些轻狂

终究不过是个普通人

无怨无悔我走我路