JS算法之快速幂

955 阅读3分钟

这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

数值的整数次方

剑指Offer 16.数值的整数次方

实现pow(x,n),即计算x的n次幂函数(即x^n)。不得使用库函数,同时不需要考虑大数问题。

示例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/2)^2 = 1/4 = 0.25

题解

法一 递归

使用递归的方法:

  • 当n=0时,任何x都返回1
  • 当n=1时,返回x
  • 当n=-1时,返回1/x

对于其他n值:

  • 当n为偶数时,myPow(x,n) = myPow(x,n/2)*myPow(x,n/2)
  • 当n为奇数时,myPow(x,n) = myPow(x,(n-1)/2)*myPow(x,(n-1)/2) * x

注意:递归时先用一个变量取得myPow(x,n/2)的值再平方,可以降低时间复杂度(减少递归调用的次数)

 /**
  * @param {number} x
  * @param {number} n
  * @return {number}
  */
 var myPow = function(x,n){
   if(n===0) return 1;
   if(n===1) return x;
   if(n===-1) return 1/x;
   if(n%2===0){
     let a = myPow(x,n/2);
     return a*a;
   }
   else{
     let b = myPow(x,(n-1)/2);
     return b*b*x;
   }
 }

法二 快速幂

假设x=3,n=5。那么5的二进制是:101。所以,3的5次方可以写成下图:

img

对x进行自乘,导致x的指数每次都扩大2倍。与n的二进制相对应。

以上图为例,整个算法的流程如下:

  • 结果值result初始为1
  • x初始为3,此时n的二进制最右位为1,更新结果为:x * n
  • n右移一位。x进行累乘,x更新为3的2次方。由于n的二进制最右位为0,不更新结果
  • n右移一位。x进行累乘,x更新为3的4次方。此时n的二进制最右位为1,更新结果为:x * result
  • 结束
 /**
  * @param {number} x
  * @param {number} n
  * @return {number}
  */
 var myPow = function(x, n) {
     let reusult = 1.0;
     //如果负数,2^-2可以变成(1/2)^2
     if(n<0){
         //js中默认不是整除
         x = 1/x;
         n = -n;
     }
     while(n>0){
         if(n&1){ // 如果n最右位是1,将当前x累乘到result
             reusult*=x;
         }
         x*=x; // x自乘法
         //>>是有符号数的移位,>>>是无符号数的移位
         //下面第一种是错误的,剩下两个都是正确的
         // n = n>>1
         // n = Math.floor(n/2)
         n = n>>>1
     }
     return reusult;
 };

打印从1到最大的n位数

剑指Offer 17.打印从1到最大的n位数

输入数字n,按顺序打印出从1到最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数999.

示例1:

 输入: n = 1
 输出: [1,2,3,4,5,6,7,8,9]

说明:

  • 用返回一个整数列表来代替打印
  • n为正整数

题解

使用内置函数即可,可以使用快速幂来优化。

 /**
  * @param {number} n
  * @return {number[]}
  */
 var printNumbers = function(n){
   let max = ''
   while(n--) max += '9'
   return new Array(max - '0').fill(0).map((val,index) => index + 1)
 }
 ​
 或
 ​
 var printNumbers = function(n) {
     let len = Math.pow(10, n)-1
     return Array.from({length: len}, (item, index) => index+1)
 };

坚持每日一练!前端小萌新一枚,希望能点个哇~