LeetCode:372.超级次方

65 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第19天,点击查看活动详情

372.超级次方

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/su…

你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出。

示例 1:

输入:a = 2, b = [3] 输出:8

示例 2:

输入:a = 2, b = [1,0] 输出:1024

示例 3:

输入:a = 1, b = [4,3,3,8,5,2] 输出:1

示例 4:

输入:a = 2147483647, b = [2,0,0] 输出:1198

提示:

1 <= a <= 231 - 1 1 <= b.length <= 2000 0 <= b[i] <= 9 b 不含前导 0

解法

  • 如果使用暴力算法,先将后面的数组拼接为整数,之后再求幂指数,会提示超时

  • 幂指数解法有一个关于快速幂的内容,即将ana^n拆分为an/2an/2a^{n/2} * a^{n/2}, 然后判断n的奇偶数,看看是否需要再乘以一个a

  • 另外列表元素组合成一个整数也可以拆成求和的形式,a121=a100+a20+a1a^{121} =a^{100}+a^{20}+a^{1}的样式,因此,列表元素如果取反之后,然后遍历的时候,每个元素遍历完再乘以10就能模拟这种大数了

  • “整除分配律”: (ab)%mod=(a%mod)(b%mod)%mod(a*b)\% mod = (a\%mod) * (b\%mod) \% mod

  • python

MOD = 1337

class Solution:
    def superPow(self, a: int, b: List[int]) -> int:
        res = 1
        x = a % MOD
        for y in b[::-1]:
            res = (res * self.quickPow(x, y)) % MOD
            x = self.quickPow(x, 10)
        return res
    
    def quickPow(self, x: int, n: int) -> int:
         res = 1
         while n:
            if n % 2 == 1:
                res = (res * x) % MOD
            n >>= 1
            x = (x * x) % MOD
         return res
  • c++
class Solution {
    const int MOD = 1337;

public:
    int quickPow(int x, int n)
    {
        int res = 1;
        x = x % MOD;
        while(n)
        {
            if(n&1)
            {
                res = (long) res * x % MOD;
            }
            x = long (x*x) % MOD;
            n >>= 1;
        }
        return res;
    }

    int superPow(int a, vector<int>& b) {
        int nSize = b.size();
        int res = 1;
        for(int i=nSize-1; i>=0; i--)
        {
            res = (long) res * quickPow(a, b[i]) % MOD;
            a = quickPow(a, 10); 
        }
        return res;
    }
};

复杂度分析

  • 时间复杂度:
    • O(logK)O(logK) 假设 b 数组所代表的数字为 K,使用快速幂的复杂度为 O(logK)O(logK),或者说是 O(nlog10)O(n * \log{10}),其中 n 为数组 b 的长度,数字 10 所代表的含义是计算一个次方为 10 以内的值;而不使用快速幂的复杂度为 O(n10)O(n*10)
  • 空间复杂度
    • O(1)O(1)