【leetcode 力扣刷题】数学题之计算次幂//次方:快速幂

利用乘法求解次幂问题---快速幂

  • [50. Pow(x, n)](#50. Pow(x, n))
  • [372. 超级次方](#372. 超级次方)

50. Pow(x, n)

题目链接:50. Pow(x, n)

题目内容:

题目就是要求我们去实现计算x的n次方的功能函数,类似c++的power()函数。但是我们不能使用power()函数直接得到答案,那样这道题就失去了考察的意义。

前面提到乘法a*b可以看作是b个a相加,用加法来完成乘法;x的n次方,就是n个x相乘,那么同样可以用乘法来代替次幂计算,我们称之为快速幂 。比如5^7,就是7个5相乘,快速幂的过程如下:

第一轮是乘以5,第二轮乘以5*5,第三轮乘以(5*5)*(5*5),也就是每一轮乘的数都在加倍,这样就能够在log^n的时间复杂度内完成x^n的计算。代码实现如下(C++):

cpp 复制代码
class Solution {
public:
    double myPow(double x, int n) {
    	//先处理特殊情况
        if(x == 0) return 0.0;
        if(x == 1) return 1.0;
        if(n == 0) return 1.0;
        bool flage = false;
        long _n = n;
        //如果n是负数,x^n = 1/(x^|n|)
        if(_n < 0){
            flage = true;
            _n = -_n;
        }
        double ans = 1;
        double mul = x;
        //快速幂主体过程
        while(_n){  
            if(_n&1)  //如果n末位为1,就乘以mul
                ans *= mul;      
            mul *= mul; //mul翻倍
            _n >>= 1; //n右移一位
        }
        return flage ? 1.0/ans : ans; //判断是否需要变成倒数
    }
};

372. 超级次方

题目链接:372. 超级次方

题目内容:

看起来和上一题是差不多的,但是由于b是一个非常大的正整数,以数组形式给出1,0,3,4就表示1034【末位是个位,然后是十位,然后是百位,最前面的是最高位】。其中1 <= b.length <= 2000说明b可以达到10^1999的程度,根本没法用double、long long等数据类型来存储这么大的数,所以在运算过程中也不能直接把b转换成一个数或者每一位转换成一个数,需要其他方法:

将每一位bi的数值bi*10^(m-1-i)【其中m是b.length】分解成bi和10^(m-1-i)两部分,每次先求a^(10^(m-1-i))得到A,再求A^bi。a^(10^(m-1-i))随着i的减小越来越大,但是可以看作是上一轮的A^10。

由于每次次幂结果都要mod 1337,所以结果是不会溢出的,a^(10^(m-1-i))每一次用上一轮的A^10来表示就解决了b很大的问题。另外需要注意的是(a*b) mod k =( (a mod k) * (b mod k) ) mod k。

a^(10^(m-1-i))和A^bi以及A^10都用快速幂求解。快速幂过程中根据(a*b) mod k =( (a mod k) * (b mod k) ) mod k加上求模操作。代码如下(C++):

cpp 复制代码
class Solution {
public:
	//快速幂
    long quick_pow(int a, int n){
        int ans = 1;
        int mul = a;
        while(n){
            if(n&1)
            	//加上求模操作
                ans = ( (ans % 1337) * (mul % 1337)) % 1337;
            //mul也加上求模操作
            mul = ((mul % 1337) * (mul % 1337)) % 1337;
            n>>=1;
        }
        return ans;
    }
    int superPow(int a, vector<int>& b) {
        int ans = 1;        
        for(int j = b.size() - 1; j >= 0; j--){
            ans =( (ans % 1337) * (quick_pow(a,b[j]) % 1337) ) % 1337;
            //每次a都在上一次的基础上,变成其10次方
            a = quick_pow(a, 10);
        }
        return ans;
    }
};
相关推荐
通信小呆呆41 分钟前
电子战抗干扰技术:当“不被干扰”成为一种系统
算法·通信·mimo·isac
笑容掩饰我的失落1 小时前
区块链从小白到精通(八):从零实现一个标准 ERC-20 代币(完整可运行代码)
算法·区块链·php·智能合约·哈希算法
Severus_black1 小时前
【C++初阶】Stack、Queue算法题大练兵!
c语言·c++·算法·stl
2601_967979124 小时前
机器学习必修课:经典算法与Python实战
python·算法·机器学习·实战·课程
程序猿打工仔4 小时前
计算机基础(C语言)考编、专技岗
c语言·开发语言·算法
通信小呆呆5 小时前
电子战干扰技术:从“蛮力压制”到“精准欺骗”,再到“认知博弈”
算法·通信·isac
老师我太想进步了20265 小时前
【数据结构-6】算法美学之单链表(1)
数据结构·算法
希望我万事顺遂6 小时前
力扣hot100-滑动窗口最大值
数据结构·算法·leetcode
꧁细听勿语情꧂6 小时前
二叉树余题,排序、直接插入排序、希尔排序
c语言·开发语言·数据结构·算法
是main不是漫7 小时前
【双指针|LeetCode1089 复写零】巧用逆向思路,破解原地覆盖陷阱
数据结构·算法·leetcode