LeetCode50/Pow(x,n)

计算xn次方

暴力求解直接乘以nn的方式可行,但是显然不是我们需要的方案。

分治

n为偶数的时候,xn次方转为xn/2的相乘,每个xn/2次方可以继续转为xn/4相乘....

n为奇数的时候,n次方转为n/2(取整)之后,多出一个x,再以相同的逻辑继续下分。

这样一来,乘法操作的次数被大大降低,时间复杂度被降到O(logn)的级别。

var myPow = function (x, n) {
  if (n === 0) {
    return 1;
  }
  if (n < 0) {
    return 1 / myPow(x, -n);
  }
  if (n % 2) {
    return x * myPow(x, n - 1);
  }
  return myPow(x * x, n / 2);
};

分析:

  1. n<0的时候,取倒数转化成n0的情况,继续递归
  2. n为奇数的情况,提取一个x出来,后面的myPow(x, n - 1)指数n-1就是偶数
  3. n为偶数的情况,转为两个xn/2次方相乘的形式
  4. 一直递归,n/2一直划分,直到n=1,递归终止将结果依次返回。

循环&位运算

对指数n的降次可以通过位运算,通过&1操作符即可判断奇偶

const newPow = (x, n) => {
  if (n < 0) {
    x = 1 / x;
    n = -n;
  }
  let pow = 1;
  while (n) {
    if (n & 1) {
      pow = pow * x;
    }
    x = x * x;
    n >>= 1;
  }
  return pow;
};

没有通过递归和分治,而是从pow=1开始循环累加的效果,偶数时,x=>x2,奇数时再把x乘到pow上,且,x=>x2。反推出来很巧妙。

原文地址:https://www.cnblogs.com/xuxiaowei/p/14502563.html