2022-03-05 每日打卡:两周周赛错题

2022-03-05 每日打卡:两周周赛错题

写在前面

“这些事儿在熟练之后,也许就像喝口水一样平淡,但却能给初学者带来巨大的快乐,我一直觉得,能否始终保持如初学者般的热情、专注,决定了在做某件事时能走多远,能做多好。” 该系列文章由python编写,所刷题目共三个来源:之前没做出来的 ;Leetcode中等,困难难度题目; 周赛题目;某个专题的经典题目,所有代码已AC。每日1-3道,随缘剖析,希望风雨无阻,作为勉励自己坚持刷题的记录。

6019. 替换数组中的非互质数

2022-03-05 每日打卡:两周周赛错题_第1张图片

  • 替换【直至满足条件问题】往往不能从前往后控制下标,而是从后往前,保证ans数组中的都是满足条件的。
class Solution:
    def replaceNonCoprimes(self, nums: List[int]) -> List[int]:
        s = [nums[0]]
        for num in nums[1:]:
            s.append(num)
            while len(s) > 1:
                x, y = s[-1], s[-2]
                g = gcd(x, y)
                if g == 1:
                    break
                s.pop()
                s[-1] *= x // g
        return s

补充复习:求最大公约数,最小公倍数,以及逆gcd:

def GCD(x, y):
   while(y):
       x, y = y, x % y 
   return x 

tmp = x * y // GCD(x, y)

def exgcd(a, b):
    if(b == 0):
        return 1,0
    # x是返回的y,y是y-x*(a//b)
    y, x = exgcd(b, a%b)
    y = y - x * (a // b)
    return x, y

2183. 统计可以被 K 整除的下标对数目

2022-03-05 每日打卡:两周周赛错题_第2张图片

  • 统计每个数的因子:考虑 n u m s [ i ] ∗ n u m s [ j ] nums[i]*nums[j] nums[i]nums[j] 是k的倍数,则 n u m s [ i ] nums[i] nums[i] 一定是 k / G C D ( n u m s [ j ] , k ) k/GCD(nums[j], k ) k/GCD(nums[j],k) 的倍数。
# 预处理每个数的所有因子,时间复杂度 O(MlogM),M=1e5
MX = 100001
divisors = [[] for _ in range(MX)]
for i in range(1, MX):
	# 只要是i的倍数的数j,都把因子i加入到divisors[j]中  
    for j in range(i, MX, i):
        divisors[j].append(i)

class Solution:
    def countPairs(self, nums: List[int], k: int) -> int:
        ans, cnt = 0, defaultdict(int)
        for n in nums:
        	# cnt是统计了nums中有多少含有因子idx的数
            ans += cnt[k / gcd(k, n)]
            # 对检查过的数的因子,加一
            for d in divisors[n]:
                cnt[d] += 1
        return ans

  • 统计k的因子:考虑 n u m s [ i ] ∗ n u m s [ j ] nums[i]*nums[j] nums[i]nums[j] 是k的倍数,则 n u m s [ i ] nums[i] nums[i] 一定是 k / G C D ( n u m s [ j ] , k ) k/GCD(nums[j], k ) k/GCD(nums[j],k) 的倍数。
class Solution:
    def countPairs(self, nums: List[int], k: int) -> int:
        divisors = set()  
        d = 1
        # 预处理 k 的所有因子
        while d <= pow(k, 0.5):  
            if k % d == 0:
                divisors.add(d)
                divisors.add(k / d)
            d += 1
        
        ans, cnt = 0, defaultdict(int)
        for n in nums:
            ans += cnt[k / gcd(k, n)]
            for d in divisors:
                if n % d == 0:
                    cnt[d] += 1
        return ans
        

你可能感兴趣的:(algorithm,leetcode,算法,贪心算法)