1、题干
给你一个正整数数组 nums,你需要从中任选一些子集,然后将子集中每一个数乘以一个 任意整数,并求出他们的和。
假如该和结果为 1,那么原数组就是一个「好数组」,则返回 True;否则请返回 False。
示例 1:
输入:nums = [12,5,7,23]
输出:true
解释:挑选数字 5 和 7。
5*3 + 7*(-2) = 1
示例 2:
输入:nums = [29,6,10]
输出:true
解释:挑选数字 29, 6 和 10。
29*1 + 6*(-3) + 10*(-1) = 1
示例 3:
输入:nums = [3,6]
输出:false
提示:
1 <= nums.length <= 10^51 <= nums[i] <= 10^9
2、思路
这不是我能写出来的题,看了提示才AC
根据提示,要求所有数字的最大公约数是否等于1。想到的思路是:先升序排序 nums 数组,如果存在相邻数字的最大公约数 gi 等于1,或者 gi 与 gcd(nums[0],nums[1]) 的最大公约数等于1,那么 nums 是一个好数组。虽然过了,但无法证明算法正确性
3、代码
function isGoodArray(nums: number[]): boolean {
    nums.sort((a, b) => a - b);
    const gcd = (a: number, b: number) => a ? gcd(b % a, a) : b;
    const g1 = gcd(nums[0], nums[1] || 0);
    for (let i = 1; i < nums.length; i++) {
        const gi = gcd(nums[i], nums[i + 1]);
        if (gi === 1 || gcd(g1, gi) === 1) return true;
    }
    return g1 === 1;
};
官解根据裴蜀定理推论和证明,严谨很多,代码也不难。整体思路也是求所有数字的最大公约数是否等于1
function isGoodArray(nums: number[]): boolean {
    let d = nums[0];
    const gcd = (a: number, b: number) => a ? gcd(b % a, a) : b;
    for (let i = 0; i < nums.length && d !== 1; i++) {
        d = gcd(d, nums[i]);
    }
    return d === 1;
};
4、复杂度
- 时间复杂度:
 - 空间复杂度:
 
5、执行结果
