题目来源:LeetCode 372. 超级次方
问题抽象: 给定一个正整数 a 和一个用数组 b 表示的非常大的正整数(数组元素依次为十进制表示的每一位),计算 a^b mod 1337 的值,满足以下核心需求:
-
核心计算:
- 结果需为
a的b次方对1337取模(即(a^b) % 1337); - 指数
b以数组形式给出(如b=[1,2,3]表示123),长度可能极大(最大2000)。
- 结果需为
-
优化目标:
- 避免直接计算大指数(
b可达10^2000量级),需通过 快速幂 和 模运算性质 分解计算:- 逐位分解:利用公式
a^b = (a^b)^10 * a^d mod 1337(b'为b去掉末位的数,d为末位); - 递归/迭代:从数组末位(个位)向高位递推计算。
- 逐位分解:利用公式
- 避免直接计算大指数(
-
数学性质:
- 模运算恒等式:
(x * y) mod 1337 = [(x * 1337) * (y mod 1337)] mod 1337; - 快速幂:计算
a^d mod 1337时(d为单数字),时间复杂度 O(log d)。
- 模运算恒等式:
-
边界处理:
- 指数为
0:若b=[0],则a^0=1(但题目保证b为正整数,通常不出现); - 底数取模:先对
a取模(a %= 1337)简化计算; - 特殊值:
a=1时结果为1;a=0时结果为0(除非b=0)。
- 指数为
-
计算约束:
- 时间复杂度 O(n log d):
n为b的长度(位数),d为单数字最大值9(快速幂最多4步); - 空间复杂度 O(1)(迭代)或 O(n)(递归栈);
- 输入范围:
1 ≤ a ≤ 2^31-1;b数组长度[1, 2000],元素值0-9(首位非0)。
- 时间复杂度 O(n log d):
输入:正整数 a,整数数组 b(表示指数)
输出:a^b mod 1337(整数)。
解题思路
题目要求计算 a^b mod 1337,其中 a 是正整数,b 是以数组形式给出的超大正整数(数组长度最大2000)。直接计算指数不可行,需结合模运算性质和快速幂算法:
-
模运算性质:
(x * y) mod 1337 = [(x mod 1337) * (y mod 1337)] mod 1337,可在计算过程中不断取模防止溢出。 -
指数分解:
设b = [b₀, b₁, ..., bₖ₋₁]表示数字n = b₀*10^(k-1) + b₁*10^(k-2) + ... + bₖ₋₁,则:
a^n = a^(b₀*10^(k-1)) * a^(b₁*10^(k-2)) * ... * a^(bₖ₋₁)
利用公式a^(m+n) = a^m * a^n和a^(m*n) = (a^m)^n分解计算。 -
快速幂算法:
高效计算a^k mod 1337,时间复杂度O(log k)。将指数转为二进制,通过平方和乘法减少计算次数。 -
逐位处理(从低位到高位):
- 初始化结果
res = 1。 - 从数组末位(个位)开始向前遍历:
- 计算
a^(当前位数值) mod 1337,乘到res上。 - 更新
a = a^10 mod 1337(为下一位的十位权重做准备)。
- 计算
- 遍历结束后
res即为最终结果。
- 初始化结果
时间复杂度:O(n),其中 n 是数组长度。每轮循环执行常数次快速幂操作(指数最大10)。 空间复杂度:O(1),仅用常数额外空间。
代码实现(Java版)🔥点击下载源码
class Solution {
private static final int MOD = 1337; // 常量模数
public int superPow(int a, int[] b) {
int res = 1;
a %= MOD; // 初始取模,避免后续乘法溢出
for (int i = b.length - 1; i >= 0; i--) {
// 计算当前位的贡献:a^(b[i]) mod MOD
res = res * quickPow(a, b[i]) % MOD;
// 更新底数:a^10 mod MOD(为下一位的十位权重做准备)
a = quickPow(a, 10);
}
return res;
}
// 快速幂计算:base^exponent mod MOD
private int quickPow(int base, int exponent) {
int result = 1;
base %= MOD; // 确保base在模范围内
while (exponent > 0) {
if ((exponent & 1) == 1) { // 指数当前位为1
result = (result * base) % MOD; // 乘入结果
}
base = (base * base) % MOD; // 底数平方
exponent >>= 1; // 指数右移(除以2)
}
return result;
}
}
代码说明
-
主函数
superPow:- 初始化结果
res=1,对a预取模防止后续溢出。 - 倒序遍历数组
b(从个位到高位):- 调用
quickPow(a, b[i])计算当前位的贡献,累乘到res并取模。 - 更新底数
a = a^10 mod MOD(为下一位的十位权重做准备)。
- 调用
- 返回最终结果
res。
- 初始化结果
-
快速幂函数
quickPow:- 通过二进制分解指数,循环处理:
- 若指数当前位为1,将当前底数乘入结果。
- 底数平方后取模,指数右移一位。
- 时间复杂度
O(log exponent),确保高效计算大指数幂。
- 通过二进制分解指数,循环处理:
提交详情(执行用时、内存消耗)

1万+

被折叠的 条评论
为什么被折叠?



