Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
chencl1986 opened this issue Aug 15, 2024 · 0 comments

Comments

@chencl1986
Copy link
Owner

原题链接:
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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant