【中等】力扣算法题解析LeetCode372:超级次方

关注文末推广名片,即可免费获得本题测试源码

题目来源:LeetCode 372. 超级次方

问题抽象: 给定一个正整数 a 和一个用数组 b 表示的非常大的正整数(数组元素依次为十进制表示的每一位),计算 a^b mod 1337 的值,满足以下核心需求:

  1. 核心计算

    • 结果需为 ab 次方对 1337 取模(即 (a^b) % 1337);
    • 指数 b 以数组形式给出(如 b=[1,2,3] 表示 123),长度可能极大(最大 2000)。
  2. 优化目标

    • 避免直接计算大指数(b 可达 10^2000 量级),需通过 快速幂模运算性质 分解计算:
      • 逐位分解:利用公式 a^b = (a^b)^10 * a^d mod 1337b'b 去掉末位的数,d 为末位);
      • 递归/迭代:从数组末位(个位)向高位递推计算。
  3. 数学性质

    • 模运算恒等式(x * y) mod 1337 = [(x * 1337) * (y mod 1337)] mod 1337
    • 快速幂:计算 a^d mod 1337 时(d 为单数字),时间复杂度 O(log d)
  4. 边界处理

    • 指数为 0:若 b=[0],则 a^0=1(但题目保证 b 为正整数,通常不出现);
    • 底数取模:先对 a 取模(a %= 1337)简化计算;
    • 特殊值
      • a=1 时结果为 1
      • a=0 时结果为 0(除非 b=0)。
  5. 计算约束

    • 时间复杂度 O(n log d)nb 的长度(位数),d 为单数字最大值 9(快速幂最多 4 步);
    • 空间复杂度 O(1)(迭代)或 O(n)(递归栈);
    • 输入范围:
      • 1 ≤ a ≤ 2^31-1
      • b 数组长度 [1, 2000],元素值 0-9(首位非 0)。

输入:正整数 a,整数数组 b(表示指数)
输出a^b mod 1337(整数)。


解题思路

题目要求计算 a^b mod 1337,其中 a 是正整数,b 是以数组形式给出的超大正整数(数组长度最大2000)。直接计算指数不可行,需结合模运算性质和快速幂算法:

  1. 模运算性质
    (x * y) mod 1337 = [(x mod 1337) * (y mod 1337)] mod 1337,可在计算过程中不断取模防止溢出。

  2. 指数分解
    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^na^(m*n) = (a^m)^n 分解计算。

  3. 快速幂算法
    高效计算 a^k mod 1337,时间复杂度 O(log k)。将指数转为二进制,通过平方和乘法减少计算次数。

  4. 逐位处理(从低位到高位):

    • 初始化结果 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;
    }
}

代码说明

  1. 主函数 superPow

    • 初始化结果 res=1,对 a 预取模防止后续溢出。
    • 倒序遍历数组 b(从个位到高位):
      • 调用 quickPow(a, b[i]) 计算当前位的贡献,累乘到 res 并取模。
      • 更新底数 a = a^10 mod MOD(为下一位的十位权重做准备)。
    • 返回最终结果 res
  2. 快速幂函数 quickPow

    • 通过二进制分解指数,循环处理:
      • 若指数当前位为1,将当前底数乘入结果。
      • 底数平方后取模,指数右移一位。
    • 时间复杂度 O(log exponent),确保高效计算大指数幂。

提交详情(执行用时、内存消耗)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

达文汐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值