快速幂实现pow函数(从二分和二进制两种角度理解快速幂)

文章目录

  • 题目
  • 思路
    • int的取值范围
    • 快速幂
      • 从二进制的角度来理解
      • 从二分法的角度来理解
  • 代码
  • 复杂度分析


题目

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


思路

想用累乘处理幂路子就走窄了,超时是板上钉钉的。

用快速幂的思想才符合题目考察的意图,在详说快速幂之前说一个很刁钻的测试用例 —— n=-2147483648

int的取值范围

我们知道:

  • int的取值范围是-2147483648-231)到2147483647231 - 1
  • -2147483648有一位符号位可用,因此2147483647是32位操作系统中最大的符号型整型常量。
  • 当出现这个刁钻的测试用例时,如果对n粗暴的取绝对值的话,int是容纳不下的,因此当 n<0 时, 需要定义一个long long类型变量 m 来存储 n 的绝对值。

快速幂

从二进制的角度来理解

  • 对于任何十进制正整数 n ,设其二进制为在这里插入图片描述
    则有:

在这里插入图片描述

  • 根据以上推导,可把计算 xn 转化为解决以下两个问题:

快速幂实现pow函数(从二分和二进制两种角度理解快速幂)_第1张图片

  • 因此,应用以上操作,可在循环中依次计算在这里插入图片描述
    的值,并将所有在这里插入图片描述累计相乘即可。

快速幂实现pow函数(从二分和二进制两种角度理解快速幂)_第2张图片
快速幂实现pow函数(从二分和二进制两种角度理解快速幂)_第3张图片


从二分法的角度来理解

快速幂实际上是二分思想的一种应用。

  • 二分推导: xn = xn/2 × xn/2 = (x2)n/2,令 n/2 为整数,则需要分为奇偶两种情况(设向下取整除法符号为 “//” ):

在这里插入图片描述

  • 幂获取结果:
  1. 根据二分推导,可通过循环 x = x2 操作,每次把幂从 n 降至 n//2 ,直至将幂降为 0
  2. sum=1 ,则初始状态 xn = xn × sum。在循环二分时,每当 n 为奇数时,将多出的一项 x 乘入 sum ,则最终可化至 xn = x0 * sum = sum,返回 sum 即可。

快速幂实现pow函数(从二分和二进制两种角度理解快速幂)_第4张图片

转自作者:jyd

算法流程:

  1. x = 0 时:直接返回 0 (避免后续 x = 1 / x 操作报错)。
  2. 初始化 sum = 1
  3. n < 0 时:把问题转化至 n≥0 的范围内,即执行 x = 1/xn = - n
  4. 循环计算:当 n = 0 时跳出;
  • n&1=1 时:将当前 x 乘入 sum(即 sum∗=x );
  • 执行 x = x2(即 x∗=x );
  • 执行 n 右移一位(即 n>>=1)。
  1. 返回 sum。

代码

class Solution {
     
public:
    double myPow(double x, int n) {
     
        if(x == 0) return 0;
        double sum = 1;
        long long m = n;
        if(n < 0){
     
            x = 1.0/x;
            m = -m;
        }
        while(m > 0){
     
            if(m & 1){
     
                sum *= x;
            }
            x *= x;
            m >>= 1;
        }
        return sum;
    }
};

复杂度分析

  • 时间复杂度 O(log_2 n): 二分的时间复杂度为对数级别。
  • 空间复杂度 O(1): sum, b 等变量占用常数大小额外空间。

你可能感兴趣的:(数据结构,算法,数据结构,c++,二分法)