来自北大算法课的Leetcode题解:1819. 序列中不同最大公约数的数目

代码仓库Github | Leetcode solutions @doubleZ0108 from Peking University.

  • 解法1(超时 7/30+):暴力,首先对数组去重,然后生成所有排列,再对每个排列计算gcd,但很容易也想到数组的排列有 2 n 2^n 2n个,肯定会超时
    • python中有很多现成的库 combinations() math.gcd(*)
  • 解法2(T76% S72%):数学法,还是要想明白循环的转化,因为排列有 2 n 2^n 2n个,循环排列肯定会超时,但数组中元素总数最多就是 1 0 5 10^5 105个,如果只循环数组是没问题的,又考虑到整个数组的最大公约数肯定不会超过最大那个数,所以可以从1~maxval循环,数据规模也不是很大的。具体而言,判断每个可能的最大公约数i(1~maxval)的倍数在不在原数组中,因为只有倍数的公约数才可能等于i,但只这一层约束是不够的,比如[3, 6, 10]如果循环到i=5虽然能找到10这个倍数,但原数组中没有子序列的最大公约数能为5,要至少能找到两个数使得他们的gcd确实等于当前的i(或者当前数本身就是i),那么可以放心大胆的让统计结果+1
class Solution:
    def countDifferentSubsequenceGCDs(self, nums: List[int]) -> int:
        nums = set(nums)
        maxVal = max(nums)
        res = 0
        for i in range(1, maxVal+1):
            g = 0
            for x in range(i, maxVal+1, i):
                if x in nums:
                    g = math.gcd(g, x)
                    if g == i:
                        res += 1
                        break
        return res

    # 解法1 超时
    def countDifferentSubsequenceGCDs1(self, nums: List[int]) -> int:
        from itertools import combinations

        nums = list(set(nums))
        subs = []
        for i in range(1, len(nums)+1):
            subs += list(combinations(nums, i))

        res = set()
        for sub in subs:
            res.add(math.gcd(*sub))
        return len(res)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

doubleZ0108

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值