leetcode372. 超级次方
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
知识点
1.递归
2.模运算
3.快速幂
思路
根据题意,要我们求得的是
a
b
m
o
d
1337
a^b \bmod {1337}
abmod1337的值,其中 b是大整数,以数组形式给出
那么我们可以对b进行分解。
假设b为[b1, b2, b3, b4, …, bk-1, bk]
那么 ab=ab1b2…bk = ab1b2…bk-1 * 10 * abk;
abk可以单独计算(bk现在是小整数),
ab1b2…bk-1 * 10又等于ab1b2…bk-1 的10次方
再根据余数的运算法则 $ (a* b) % p= ((a % p) * (b % p)) % p$
这样将大问题转换为小问题
关键点
求 a k a^k ak可以用快速幂求末位的幂,求完末位的幂,前面的位数别忘记乘10
代码
- 语言支持:C++
C++ Code:
class Solution {
public:
const int mod = 1337;
int qmi(int a, int b) // 快速幂模板
{
int res = 1;
a %= mod;
while(b)
{
if(b&1) res = res * a % mod;
b >>= 1;
a = a * a % mod;
}
return res;
}
int superPow(int a, vector<int>& b) {
if(b.empty()) return 1; // 如果b位0次幂,则结果为1
int k = b.back(); // 取出末位
b.pop_back();
return qmi(superPow(a, b), 10) * qmi(a, k) % mod; //递归求解
}
};
复杂度分析
令 n 为数组长度。
- 时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)
- 空间复杂度: O ( n ) O(n) O(n)