LeetCode题解:1250. 检查「好数组」,裴蜀定理,详细注释

原题链接:
https://leetcode.cn/problems/check-if-it-is-a-good-array/

关于裴蜀定理:

  1. 裴蜀定理是关于最大公约数的定理
  2. 裴蜀定理的含义为:如果有不全为0的整数ab,它们的最大公约数为g,那么对任意整数xy,都满足x * a + y * b = n * gn为整数。
  3. 裴蜀定理的推论:如果有整数a1, a2, ...an,其中有任意两个数是互质(最大公约数为1)的,那么就存在整数x1, x2, ...xn,使得x1 * a1 + x2 * a2 + ...xn * an=1(参考n个整数间的裴蜀定理

使用欧几里得算法计算最大公约数

  1. 如果有两个数a0,那么它们的最大公约数是a
  2. 如果有两个数4218,它们的最大公约数是g
    • 由于42 % 18 = 2442可以拆分为1824。由于42可以被g整除,18也可以被g整除,那么24也一定可以被g整除。那么,问题就被转换为了求2418的最大公约数
    • 2418可以转换成186
    • 186可以转换成126
    • 126可以转换成66
    • 66可以转换成60
    • 最后可求得4218的最大公约数为6

将欧几里得算法转换成代码:

  1. 方法一:递归
const gcd = (num1, num2) => {
  return num1 === 0 ? num2 : gcd(num2 % num1, num1)
}
  1. 方法二:迭代
const gcd = (num1, num2) => {
  while (num1) {
    const temp = num2
    num2 = num1
    num1 = temp % num1
  }

  return num2
}

解题思路:

  1. 基于以上分析,那么该题就转换成了:在nums中,是否有两个数是互质的
  2. 假设nums[1]nums[4]互质,那么从nums[0]一直到nums[4]的所有数字,最大公约数是1
  3. 因此我们只要计算除nums[0]nums[3]的最大公约数,与nums[4]的最大公约数为1即可
  4. 一旦nums中有两个数的最大公约数为1,那么nums中所有数字的最大公约数就是1nums一定是个“好数组”
/**
 * @param {number[]} nums
 * @return {boolean}
 */
var isGoodArray = function(nums) {
  // 缓存依次对数组每一项求解的最大公约数
  // 初始值可以是任意值,nums[0]的最大公约数就是其自身
  // 最大公约数的求解会从nums[0]开始,所以无需设置初始值为nums[0]
  let divisor = 0

  for (const num of nums) {
    // 计算已知最大公约数和num的最大公约数
    divisor = gcd(divisor, num)

    // 如果已遍历数字的最大公约数为1,那么nums的最大公约数只能是1,可提前退出
    if (divisor === 1) {
      break
    }
  }

  // 如果nums的最大公约数为1,就是一个好数组
  return divisor === 1
};

// 计算最大公约数(greatest common divisor)的函数
const gcd = (num1, num2) => {
  // 如果num2 < num1,两个数会被对调
  return num1 === 0 ? num2 : gcd(num2 % num1, num1)
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值