快速幂算法
1 简介
快速幂(平方求幂)算法,是一种计算乘方的简单有效的算法,它可以在O(log n)的时间复杂度下进行求幂操作。快速幂算法的数学表示如下:
2 分析
为什么快速幂算法能够在O(log n)的时间复杂度下工作呢?
我们以
方法1:最朴素的想法,
这样算无疑太慢了,尤其对计算机的CPU而言,每次运算只乘上一个个位数,无疑太屈才了。这时我们想到,也许可以拆分问题。
方法2:先算2的5次方,即
但这并不是最优解,因为对于“2的5次方”,我们仍然可以拆分问题。
方法3:先算
模仿这样的过程,我们得到一个在
3 算法实现
递归实现:
public int qpow(int a, int n) {
if(n == 0) {
return 1;
}else if(n % 2 == 1) {
return qpow(a, n - 1) * a;
} else {
int temp = qpow(a, n / 2); // 注意不能直接return qpow(a, n / 2) * qpow(a, n / 2), 否则会退化为O(n)。
return temp * temp;
}
}
非递归实现
public int qpow(int a, int n) {
int ans = 1;
while(n != 0) {
if((n & 1) != 0) { // 判断二进制数的末位为0还是为1
ans *= a;
}
n >>= 1; // 将二进制数右移一位,也相当于/2
a *= a;
}
return ans;
}
非递归形式比较难以理解,作如下解释(以
我们将幂指数n以二进制形式表示,则
最初ans为1,然后我们一位一位算:
1010的最后一位是0,所以
这一位不要。然后1010变为101,a变为 。 101的最后一位是1,所以
这一位是需要的,乘入ans。101变为10,a再自乘。 10的最后一位是0,跳过,右移,自乘。
然后1的最后一位是1,ans再乘上
。循环结束,返回结果。
针对如上所述过程,我们总结如下:
-
如果幂指数二进制表示的末位数为1,则需要将此时的a乘入ans中;
-
如果末位数为0, 则无需将a乘入ans,但是需要让
。
a依次变为
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理