leetcode:372.超级次方

题目

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-pow

你的任务是计算 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

解法

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

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

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

  • “整除分配律”: ( a ∗ b ) % m o d = ( a % m o d ) ∗ ( b % m o d ) % m o d (a*b)\% mod = (a\%mod) * (b\%mod) \% mod (ab)%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 ( l o g K ) O(logK) O(logK) 假设 b 数组所代表的数字为 K,使用快速幂的复杂度为 O ( l o g K ) O(logK) O(logK),或者说是 O ( n ∗ log ⁡ 10 ) O(n * \log{10}) O(nlog10),其中 n 为数组 b 的长度,数字 10 所代表的含义是计算一个次方为 10 以内的值;而不使用快速幂的复杂度为 O ( n ∗ 10 ) O(n*10) O(n10)
  • 空间复杂度
    • O ( 1 ) O(1) O(1)

おすすめ

転載: blog.csdn.net/uncle_ll/article/details/121734092