Skip to main content

372.超级次幂

标签: math

难度: Medium

通过率: 35.12%

原题链接: https://leetcode.com/problems/super-pow/description/

题目描述

计算 abmod1337a^b \mod 1337,其中 aa 是一个正整数,bb 是一个以数组形式给出的极大正整数。

解题思路

由于 bb 是一个超大的正整数,因此我们不能直接计算 aba^b,解决这个问题的关键在于使用模幂算法和阶乘营造出一种递归的方式来逐步减少问题的规模。

可以应用以下递归公式:

ab×10+c(a10)b×acmod1337a^{b \times 10 + c} \equiv (a^{10})^{b} \times a^c \mod 1337

首先,我们定义一个帮助函数 superPow(a, b),这个函数将对数组 bb 的每一位进行递归。

在该方法中:

  • 如果 bb 是空数组,返回 1,因为任何数的 0 次方都等于 1。
  • 我们取数组 bb 的最后一位(cc),然后从 bb 中去掉它。递归应用:
    • 计算 part1=(superPow(a,b))10mod1337part1 = (superPow(a, b))^{10} \mod 1337
    • 计算 part2=acmod1337part2 = a^c \mod 1337
    • 结果是 (part1×part2)mod1337(part1 \times part2) \mod 1337

这通过抵消掉因为 bb 太大而无法直接计算的问题,逐步减少 bb 的大小,直到可以被合理处理。

代码实现

def superPow(a, b):
# 定义递归函数
def helper(a, b):
if not b:
return 1
last_digit = b.pop()
part1 = pow(helper(a, b), 10, 1337) # 计算我们递归的部分
part2 = pow(a, last_digit, 1337) # 计算这个最后一位的幂
return (part1 * part2) % 1337

return helper(a, b) # 调用辅助函数

复杂度分析

时间复杂度:O(n)O(n),其中nn是数组bb的长度。因为我们对每一位调用递归函数,所以线性依赖于bb的大小。

空间复杂度:O(n)O(n),在最坏情况下,我们会对每个数组项进行递归调用,因此,递归栈的深度为bb的长度。