[算法] 快速幂

下面的代码均为 C++ 代码!

1. 普通快速幂

  • 例题:50. Pow(x, n)

    • 解法:递归或者迭代(时间复杂度均为O(log n),递归空间复杂度为 O(log n),迭代空间复杂度为 O(1) );
  • 迭代算法详解:(参考了官方题解:Pow(x, n) - 方法二:快速幂+迭代

    我们的目标是求 xn 次方。任何一个整数都可以用2的幂次方的和表示,这里就不证明了(学计算机的应该不至于这点都不会),因此可以使用二进制表示/存储(说白了就是数的二进制),例如5的二进制是101。即任意一个整数 n,有

    n=a020+a121+...+ak2k

    其中 a 为系数,取值为 0或1。

    因此,

    (1)xn=x(a020+a121+...+ak2k)(2)=xa020·xa121· ... ·xak2k

    由于,

    (3)x2(b+1)=x(2b·21)=x(2·2b)=x(2b+2b)=x2b·x2b (4)x2(b+1)=x2b·x2b=[x2b]2

    因此,可以从 x(即 x20)开始平方得到 x21x21再平方得到 x22,...,直到得到 x2k 。在平方的过程中我们只需要在n的相应的二进制位为1时将相应的累平方乘以前面的结果就可(例如 n 的 第c位 为1,则将 x2c 乘以 answer 就可,answer是快速幂的结果,详细看下面的代码),直至遍历完 n 的所有位!

    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]; } };
posted @   小贼的自由  阅读(48)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示