11.检查「好数组」

这是第11个算法,是个困难题,今天来啃着个硬骨头,力扣链接

给你一个正整数数组 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

看到这道题的时候其实不用慌,现将问题分解一下,首先什么情况下会满足ax+by=d,这里就要引入一个新的定理,裴蜀定理,一下贴图来自维基百科

关注这里面的一句话:特别来说,方程 ax+by=1 有整数解当且仅当整数 a 和 b 互素。

问题转换:如果存在两个互质的数就证明有解,互质的特点是两个数的最大公约数为1,如果两个数互质,那么整个数组的最大公约数就会为1。

公约数方法实现如下:

func gcd(a, b int) int {  
    if b == 0 {  
       return a  
    }  
    return gcd(b, a%b)  
}

因而可以推出代码实现如下:

func isGoodArray(nums []int) bool {  
    g := 0  
    for _, num := range nums {  
       g = gcd(num, g)  
    }  
    return g == 1  
}  
  
func gcd(a, b int) int {  
    if b == 0 {  
       return a  
    }  
    return gcd(b, a%b)  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值