算法学习第七天

139 阅读1分钟

  今天也是来一道数字题,比较特别的题。leetcode 第50题-Pow(x,n)。不使用语言内置函数库,计算x的n次幂。

实现 pow(x, n) ,即计算 x 的 n 次幂函数。
示例:
输入: 2.00000, 10
输出: 1024.00000

说明:
-100.0 < x < 100.0
n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

  以本人蹩脚的小学数学知识,能想到的就是进行for循环相乘了。但后面发现以这种空间复杂为O(n)的解法,在大数量相乘会出现超出时间限制。

var myPow = function(x, n) {
  let res = 1;
  let count = Math.abs(n)
  for (let i = 0; i < count; i++) {
    res = res * x
  }
  if (n < 0) res = 1 / res
  return res
};

  于是研究了下大神的解法,发现原来只需要换个角度就能达到O(log n)的解法。比如2^10 = 2^5 * 2^5,然后2^5 = 2^2 * 2^2 * 2^1。一层一层地减小计算的次数,即可优化到O(log n)的时间复杂度。

var myPow = function(x, n) {
    let res = 1;
    let count = Math.abs(n)
    res = helper(x, count)
    if (n < 0) res = 1 / res
    return res
};

function helper (x, count) {
    const mid = parseInt(count / 2) 
    if (count < 1) return 1
    const r = helper(x, mid) // 提前把结果给缓存起来,后面直接使用,避免重复的运算
    if (count % 2 == 0) return r * r
    return r * r * x
}

  这种解法是分治算法,基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,进行合并就可得到原问题的解。
  相同道理,可以解决另一个问题(不使用内置函数,求n乘k的结果)。可以继续尝试下。