【双周赛】第74场双周赛

本文介绍了四道编程竞赛题目,涉及数组处理和字符串操作。第一题检查数组中所有数字出现次数是否为偶数;第二题使用贪心策略寻找字符串中最多子序列;第三题通过堆数据结构实现数组和减半的最小操作次数;第四题未给出解题详情。文章详细解析了解题思路和关键代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

6020. 将数组划分成相等数对

在这里插入图片描述

第一题很简单,不到一分钟就可以做出来了。思路就是统计每一个数字出现的次数,只有所有数字都出现过偶数次,才满足要求。

class Solution:
    def divideArray(self, nums: List[int]) -> bool:
        # 判断数组是否每一个数字都出现过偶数次
        dic = collections.defaultdict(int)
        
        for i, num in enumerate(nums):
            dic[num] += 1
        
        for k, v in dic.items():
            if v % 2 == 1:
                return False
            
        return True

6021. 字符串中最多数目的子字符串

在这里插入图片描述
这一题没做出来。主要是因为对贪心法做得少。

贪心的思路是:
根据题意,设pattern中第一个字母为x,第二个字母为y,那么肯定是x越靠左越好,y越靠右越好(这一点当时都没想到)。于是可以直接把x放在最左侧或者y放在最右侧,每遇到一个y就统计左边x的个数。

需要注意的是,如果放x,那么相比于放之前,肯定多的子字符串个数是cy(cy为test中y出现的次数)。
如果放y,比之前做的子字符串个数为cx(cx为test中x出现的次数)。这样的话,我们就可以一次遍历解决两种情况了。

那么怎么计算text中本来有多少个pattern呢,其实在遍历的时候就可以直接计算y左边有多少个x,然后直接累加就行了。

class Solution:
    def maximumSubsequenceCount(self, text: str, pattern: str) -> int:
        # 如果x==y,此时可以直接遍历text计算有多少个x,那么加上一个,之后用组合公式即可
        if pattern[0] == pattern[1]:
            cx = 0
            for t in text:
                if t == pattern[0]:
                    cx += 1
            return cx * (cx + 1) // 2
        
        res = 0
        x, y = pattern[0], pattern[1]
        cx = cy = 0

        for i in range(len(text)):
            if text[i] == x:
                cx += 1
            elif text[i] == y:
                cy += 1
                res += cx   # 当前y左边有多少个x,那么以该y为第二个元素的子字符串就有多少个
        
        return res + max(cx, cy)

6022. 将数组和减半的最少操作次数

在这里插入图片描述
这次双周赛,第三题并不难。其实也算贪心的方法,每次把最大的那个数减半,第二次再把当前最大的数减半,以此类推直到总和小于原来的一半,但是这样每次都要排序,很耗时。此时就可以想到有一种数据结构可以在拿出或者放入元素的时候自动维护有序,那就是
不过python中是最小堆,所以我们需要把每个数字都转换成负数,最后求和也不是判断总和小于之前的一半,而是当总和小于之前一半的时候一致循环。

另外一点要注意的是,不需要每次都重新计算总和,这样的话会超时。我们每次都知道前一次的总和,而这次减小了多少我们也知道,所以可以直接计算,不需要对整个数组重新求和。

class Solution:
    def halveArray(self, nums: List[int]) -> int:
        # 每次从最大的数字开始减小,但是减小后还需要重新对数组排序,这很耗时
        # 可以维护一个最大堆
        q = []
        for num in nums:
            heapq.heappush(q, -num)
        
        total = sum(q)
        res = 0
        new_sum = total
        while new_sum < (total / 2):
            res += 1
            num = heapq.heappop(q)
            num = num / 2
            new_sum -= num    # 新的数组和减少了num
            heapq.heappush(q, num)
        
        return res

6023. 用地毯覆盖后的最少白色砖块

pass

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值