这是第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)
}