【我也想刷穿 LeetCode】372. 超级次方

128 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

现在前端很多岗位面试需要有一定的算法基础,或者说经常刷算法的会优先考虑。

因此每天刷刷LeetCode非常有必要

在这之前我也刷过一些算法题,也希望以后也坚持刷,跟某掘友一样,我也想刷穿 LeetCode

一、题目描述

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

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/su… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思路分析

b是一个数组,不能表示成整型,而且数组的特点是随机访问,删除最后一个元素比较高效 以 b = [1,5,6,4]来举例,结合指数运算的法则,我们可以发现这样的一个规律

(a * b) % base这样的运算,乘法的结果可能导致溢出,我们希望找到一种技巧,能够化简这种表达式,避免溢出同时得到结果 (a*b)%k = (a%k)(b%k)%k 也就是说对乘法的结果求模,等价于先对每个因子都求模,然后对因子相乘的结果再求模。

三、代码实现

/**
 * @param {number} a
 * @param {number[]} b
 * @return {number}
 */
let base = 1337;
/* 计算 a 的 k 次方然后与 base 求模的结果 */
let mypow = function (a, k) {
  // 公式
  // (a*b)%k = (a%k)(b%k)%k
  // 对因子求模
  a %= base;
  let res = 1;
  for (let i = 0; i < k; i++) {
    // 先对因子a求模,然后每次都对乘法结果res求模,这样可以保证res *= a这句代码执行时两个因子都是小于base的,也就一定不会造成溢出
    res *= a;
    // 对乘法结果求模
    res %= base;
  }
  return res;
};
var superPow = function (a, b) {
  if (!b.length) return 1;
  let last = b.pop();
  let part1 = mypow(a, last);
  let part2 = mypow(superPow(a, b), 10);
  // 每次乘法都要求模
  return (part1 * part2) % base;
};

四、总结

以上就是本道题的所有内容了,本系列会持续更,欢迎点赞、关注、收藏,另外如有其他的问题,欢迎下方留言给我,我会第一时间回复你,感谢~