[算法] 快速幂
下面的代码均为 C++ 代码!
1. 普通快速幂
-
- 解法:递归或者迭代(时间复杂度均为,递归空间复杂度为 ,迭代空间复杂度为 );
-
迭代算法详解:(参考了官方题解:Pow(x, n) - 方法二:快速幂+迭代)
我们的目标是求 的 次方。任何一个整数都可以用2的幂次方的和表示,这里就不证明了(学计算机的应该不至于这点都不会),因此可以使用二进制表示/存储(说白了就是数的二进制),例如5的二进制是101。即任意一个整数 ,有
其中 为系数,取值为 0或1。
因此,
由于,
因此,可以从 (即 )开始平方得到 ,再平方得到 ,...,直到得到 。在平方的过程中我们只需要在n的相应的二进制位为1时将相应的累平方乘以前面的结果就可(例如 n 的 第c位 为1,则将 乘以 answer 就可,answer是快速幂的结果,详细看下面的代码),直至遍历完 的所有位!
class Solution { double quickMul(double x, long long n) { double answer = 1.0; double squareX = x; // x,即为x^(2^0) while (n > 0) { if (n % 2 != 0) { // 最后一位为1,则说明该 answer *= squareX; } squareX *= squareX; // 累平方 n >>= 1; // n右移一位,也可以将n除以2 } return answer; } public: // 求x的n次方 double myPow(double x, int n) { return n > 0 ? quickMul(x, n) : 1.0 / quickMul(x, -(long long)n); } };
2. 矩阵快速幂(了解)
-
下面为求裴波那契数列的第n项的代码(详细看上面的链接):
// 定义一个 Solution 类封装需要的函数 class Solution { const int MOD = 1000000007; // 2*2矩阵(方阵)乘法 vector<vector<long long>> matrixMul(vector<vector<long long>> &x, vector<vector<long long>> &y) { vector<vector<long long>> res(2, vector<long long>(2)); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { res[i][j] = (x[i][0] * y[0][j] + x[i][1] * y[1][j]) % MOD; } } return res; } // 矩阵快速幂 vector<vector<long long>> fastExponentiation(vector<vector<long long>> &x, int n) { vector<vector<long long>> res = {{1, 0}, {0, 1}}; // 单位矩阵 vector<vector<long long>> exponent = x; // 2^0 while (n) { if (n & 1) { res = matrixMul(res, exponent); } exponent = matrixMul(exponent, exponent); n >>= 1; } return res; } public: int fib(int n) { vector<vector<long long>> x = {{1, 1}, {1, 0}}; // 定义矩阵M return n < 2 ? n : fastExponentiation(x, n - 1)[0][0]; } };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)