写点什么

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

作者:Lee Chen
  • 2024-08-15
    福建
  • 本文字数:1050 字

    阅读完需:约 3 分钟

原题链接: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

  3. 由于42 % 18 = 2442可以拆分为1824。由于42可以被g整除,18也可以被g整除,那么24也一定可以被g整除。那么,问题就被转换为了求2418的最大公约数

  4. 2418可以转换成186

  5. 186可以转换成126

  6. 126可以转换成66

  7. 66可以转换成60

  8. 最后可求得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)}
复制代码


发布于: 刚刚阅读数: 4
用户头像

Lee Chen

关注

还未添加个人签名 2018-08-29 加入

还未添加个人简介

评论

发布
暂无评论
LeetCode题解:1250. 检查「好数组」,裴蜀定理,详细注释_Lee Chen_InfoQ写作社区