[LeetCode周赛复盘] 第 107 场双周赛20230624

本周LeetCode周赛涵盖了字符串连接删减字母、构造最长新字符串、统计未收到请求的服务器数目等题目,解题策略包括哈希表模拟、记忆化搜索和动态规划。对于字符串连接问题,关键在于模拟过程;构造最长新字符串则需利用记忆化搜索优化;统计服务器数目采用离线处理结合滑窗方法。
摘要由CSDN通过智能技术生成

一、本周周赛总结

  • T1 哈希表模拟。
  • T2 记忆化搜索。
  • T3 dp。
  • T4 离线+滑窗。
    在这里插入图片描述

6898. 字符串连接删减字母

6898. 字符串连接删减字母

1. 题目描述

在这里插入图片描述

2. 思路分析

按题意模拟即可。

  • 注意每个单词只能匹配一次,记得删除。

3. 代码实现

class Solution:
    def maximumNumberOfStringPairs(self, words: List[str]) -> int:
        p = set()
        ans = 0
        for w in words:
            s = w[::-1]
            if s in p:
                ans += 1
                p.remove(s)
            else:
                p.add(w)
        return ans 

6895. 构造最长的新字符串

6895. 构造最长的新字符串

1. 题目描述

在这里插入图片描述

2. 思路分析

记忆化搜索
  • 令f(x,y,z,last)为用xyz个对应串,构造尾巴为last=a/b字符的最长串长度。
  • 那么若last='a’则只能用x,可以从f(x-1,y,z,last=‘b’)转移而来,若转移不了,则可以只用一个x,最山是2;
  • 若last=‘b’则可以用y/z,同理从对应尾字符转移而来。

3. 代码实现

class Solution:
    def longestString(self, x: int, y: int, z: int) -> int:

        @cache
        def f(x, y, z, last):                         
            ans = -inf
            if last == 'a':                
                if x > 0 :
                    ans = max(ans,f(x-1,y,z,'b')+2,2)
            elif last == 'b':                
                if y>0:
                    ans = max(ans,f(x,y-1,z,'a')+2,2)
                if z>0:
                    ans = max(ans,f(x,y,z-1,'b')+2,2)
            
            return ans 
          
        return max(f(x,y,z,'a'),f(x,y,z,'b'))

6898. 字符串连接删减字母

6898. 字符串连接删减字母

1. 题目描述

在这里插入图片描述

2. 思路分析

  • dp。
  • 由于连接顺序是固定的,影响只在之前串的首尾字符,那么可以记录每次转移完,首尾字符分别为x,y时的最小长度,然后进行分类讨论。
  • 令f[i][(x,y)]为用了前i个字符串,首尾分别为xy时最小长度。
  • 转移时,尝试把当前串s和前边所有串进行连接。
  • 由于只有小写字符,因此状态数最多26*26,转移1000次即可。

  • 实现时图方便用了defaultdict,并且可以滚动省去一维。

3. 代码实现

class Solution:
    def minimizeConcatenatedLength(self, words: List[str]) -> int:
        n = len(words)
        f = defaultdict(lambda : inf)
        a = words[0]
        f[(a[0],a[-1])] = len(a)
        
        for i in range(1,n):
            a = words[i]
            p = len(a)
            g = defaultdict(lambda : inf)
            for (s,e),v in f.items():
                if a[0] == e:
                    g[(s,a[-1])] = min(g[(s,a[-1])], v+p-1)
                else:
                    g[(s,a[-1])] = min(g[(s,a[-1])], v+p)
                if a[-1] == s:
                    g[(a[0],e)] = min(g[(a[0],e)],v+p-1)
                else:
                    g[(a[0],e)] = min(g[(a[0],e)],v+p)
            f = g
        return min(f.values())

6468. 统计没有收到请求的服务器数目

6468. 统计没有收到请求的服务器数目

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 离线+滑窗。
  • 读题愣了一下,logs这个变量名也有点坑人。敲成了log运行,但是白板不报错,RE 3次。
  • 发现把询问离线,把事件排序,然后用cnt记录窗口内每个服务器的出现次数即可。
  • 然后用n减去出现了几个服务器就是没出现的个数。

3. 代码实现

class Solution:
    def countServers(self, n: int, logs: List[List[int]], x: int, queries: List[int]) -> List[int]:
        m = len(queries)
        ans = [0]*m
        j = 0
        logs.sort(key=lambda xx:xx[1])
        q = deque()
        cnt = Counter()
        for v,i in sorted([(v,i) for i,v in enumerate(queries)] ):
            while j < len(logs) and logs[j][1] <= v:
                q.append(j)
                cnt[logs[j][0]] += 1
                j += 1
            while q and logs[q[0]][1]<v-x:
                p = logs[q.popleft()][0]
                cnt[p] -= 1
                if not cnt[p]:
                    del cnt[p]
            ans[i] = n - len(cnt)
        return ans                                    

参考链接

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值