Leetcode 3312. Sorted GCD Pair Queries

1. 解题思路

这一题的话坦率来说没有搞定,后来是找的大佬的代码抄了一下……

整体来说这道题思路上还是比较暴力的,还是一个二重循环,不过我是最暴力的二重循环,大佬稍微做了一下优化……

首先给出我的代码如下:

class Solution:
    def gcdValues(self, nums: List[int], queries: List[int]) -> List[int]:
        cnt = Counter(nums)
        nums = sorted(cnt.keys())
        m = max(nums)
        s = [0 for _ in range(m+1)]

        n = len(nums)
        for i in range(n):
            x = nums[i]
            s[x] += cnt[x] * (cnt[x]-1) // 2
            for j in range(i+1, n):
                y = nums[j]
                c = gcd(x, y)
                s[c] += cnt[x] * cnt[y]

        s = list(accumulate(s))
        return [bisect.bisect_right(s, q) for q in queries]

可以看到,就是两两求最大公约数,然后通过二分检索的方式求query的结果。而这个方法不出所料地超时了。

然后大佬们的优化点在于不是两两求最大公约数了,而是直接将所有可能的因数罗列出来,然后求每一个数作为最大公约数时的个数。

而对于具体的求法类似于求全部质数,即对每一个数,其作为最大公约数的个数为所有倍数上的数的个数总和取 C n 2 C_n^2 Cn2,然后减去其倍数上所有的数的最大公约数的数目。

如此一来的话差不多就是将时间复杂度从 O ( N 2 ) O(N^2) O(N2)减至 O ( N 3 / 2 ) O(N^{3/2}) O(N3/2)

2. 代码实现

给出python代码实现如下:

class Solution:
    def gcdValues(self, nums: List[int], queries: List[int]) -> List[int]:
        cnt = Counter(nums)
        nums = sorted(cnt.keys())
        m = max(nums)
        s = [0 for _ in range(m+1)]
        
        for i in range(m,0,-1):
            vc = sum(cnt[x] for x in range(i,m+1,i))
            vc = vc*(vc-1)//2 - sum(s[x] for x in range(i,m+1,i))
            s[i]=vc
        s = list(accumulate(s))
        
        return [bisect.bisect_right(s, q) for q in queries]

提交代码评测得到:耗时1627ms,占用内存42.2MB。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值