【算法通关】1250. 检查「好数组」——裴蜀定理

5,193 阅读2分钟

「这是我参与2022首次更文挑战的第5天,活动详情查看:2022首次更文挑战

用任选和任意来描述存在问题,按照结果导向应该是存在的意思吧

——leetcode此题热评

前言

大家好,我是一条,欢迎来到我的算法频道。

只做有趣的算法题,只为面试写算法

Question

1250. 检查「好数组」

难度:困难

给你一个正整数数组 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, 61029*1 + 6*(-3) + 10*(-1) = 1

示例 3:

输入:nums = [3,6]
输出:false

提示:

1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9

Solution

看到是一道困难题,也是有点慌,不过硬着头皮也是要上。

在这里说一下做算法题的一般解题步骤:

  • 理解题目
  • 注意数据范围
  • 理解样例

大多是leetcode题都非常简短,信息往往就在不经意的地方,比如数据范围和样例。

本题我们先读一遍题……,发现问的是否存在?那我们需要把所有情况都计算一遍吗?

显然不是,即使写出来也超时了。

往下看案例,前两个没发现有什么规律,看最后一个:

输入:nums = [3,6]
输出:false

突然明白,如果两个数是倍数关系,那无论怎么乘,相加都不会是1,再回过头看:

利用裴蜀定理,自左至右求出最大公因数即可 若最大公因数为1,一定存在两两互质的最大公因数,可以(使用这两个互质的公因数)实现「好数组」

注:最大公因数可以通过有限次乘法运算求出 若最大公因数不为1,所有数都有共同的(大于1的)公因数,不能实现「好数组」

Code

/**
 * @author 一条coding
 */
public boolean isGoodArray(int[] nums) {
    int len = nums.length, res = nums[0];
    for(int i = 1; i < len; i ++){
        res = gcd(res, nums[i]);
    }
    return res == 1;
}

public static int gcd(int a, int b){
    return b == 0 ? a : gcd(b, a % b);
}

最后

点赞,点赞,还TMD是点赞!