快速幂

概率

顾名思义,快速幂就是快速算底数的 n 次幂。其时间复杂度为 O(log₂N),与朴素的 O(N) 相比效率有了极大的提高。

原理

使用求 a 的 b 次方来解释。把 b 转换成二进制数,该二进制数第 i 位的权为 2^{i-1}。例如:a^{11}=a^{2^{0}+2^{1}+2^{3}},11 的二进制为 1011,即 11=1*2^{3}+0*2^{2}+1*2^{1}+1*2^{0},因此,可以将 a^{11} 转化为算 a^{2^{0}+2^{1}+2^{3}}。这样原来计算 a^{11} 需要计算 11 次,通过快速幂只需要计算 3 次。从而降低了算法的复杂度。

算法思路

使用位运算。

1)当 b 是奇数时,那么有 a^{b}=a*a^{b-1}

2)当 b 是偶数时,那么有 a^{b}=a^{\frac{b}{2}}*a^{\frac{b}{2}}

代码实现

最朴素的求幂方法

使用简单的累乘,代码如下,暂时不考虑数据越界问题。

int Pow(int a, int b){
    int ans = 1;
    for (int i = 0; i<b; i++){
        ans *= a;
    }

    return ans;
}

可以看出,该算法的时间复杂度为 O(n)。

递归版快速幂

int Pow(int a, int b) {
    if (0==b) {
        return 1;
    }
    if (b&1) {
        //b为奇数
        return a*Pow(a, b-1);
    } else {
        //b为偶数
        int t = Pow(a, b/2);
        return t*t;
    }
}

可以看出,该算法的时间复杂度为 O(logb),也就是 O(logn)。

迭代版快速幂

int Pow(int a, int b) {
    int result=1;
    int base=a;

    while (b) {
        if (b&1) {
            result *= base;
        }
        base *= base;
        b >>= 1;
    }

    return result;
}

可以看出,该算法的时间复杂度为 O(logb),也就是 O(logn)。

base *= base解析

因为 base * base == base^{2},下一步再乘,就是 base^{2}*base^{2}==base^{4},然后再乘 base^{4}*base^{4}==base^{8},由此可以推导出 base\rightarrow base^{2}\rightarrow base^{4}\rightarrow base^{8}......。可以发现指数正是 2^{i}

再看上面解析的例子 a^{11}=a^{2^{0}+2^{1}+2^{3}},这三项就可以完美解决了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章