Leetcode刷题笔记--大数取余

目录

1--大数取余

2--循环取余

3--快速幂取余

4--代码实例


1--大数取余

给定大数 a^n,返回其对 p 取余的结果,即 a^n % n;

2--循环取余

主要原理:

        基于 (a * b) % p = [(a % p) * (b % p)] % p;则 a^n % p = [(a % p) * a^(n-1) % p] % p,用一个变量 res 记录当前的 a^(n-1) % p,循环计算和更新 res;(类似于动态规划,递推过去);

        循环遍历 n,复杂度为 O(n);

// 循环取余 计算 a^n % p
long long pow(long long a, long long n, long long p){
    long long res = 1;
    a = a % p;
    for(int i = 1; i <= n ; i++){
        res = (res * a) % p;
    }
    return res;
}

3--快速幂取余

主要原理:原理讲解参考

        a^n%p = a^(2*(n/2))) = ((a^2)%p)^(n/2)%p;

        n为偶数时,a^n%p = (a^2 % p)^(n//2)%p;

        n为奇数时,a^n%p = [(a%p)(a^(n-1)%p)]%p; 即将 n-1 转化为偶数;

速记:

        指数 n 为偶数时,将底数a与自身相乘,将指数 n 整除 2;

        指数 n 为奇数时(用 n % 2 == 1 为 true 判断),先将一个 a 提出来与当前结果相乘,再将底数与自身相乘,最后将指数 n 整除 2;

        不断循环 n,直到 n == 0 结束,复杂度为 O(log_n);

// 快速幂取余 计算 a^n % p
long long fast_pow(long long a, long long n, long long p){
    long long res = 1;
    a = a % p;
    while(n){
        // 奇数
        if(n%2 == 1){
            res = (res * a) % p;
        }
        a = a * a;
        n = n / 2;
    }
    return res;
}

4--代码实例

class Solution(object):
    def cuttingRope(self, n):
        if n <= 3:
            return n - 1
        num = n / 3
        mod = n % 3
        p = 1000000007
        if mod == 0:
            return self.pow(3, num, p)
        elif mod == 1:
            return self.pow(3, num-1, p) * 4 % p
        else: 
            return self.pow(3, num, p) * 2 % p

    def pow(self, a, n, p):
        a = a % p
        res = 1
        for i in range(n):
            res = (a * res) % p
        return res
    
    def fast_pow(self, a, n, p):
        a = a % p
        res = 1
        while(n):
            if(n%2 == 1):
                res = res * a % p
            a = a*a
            n = n /2
        return res

猜你喜欢

转载自blog.csdn.net/weixin_43863869/article/details/131113547