[LeetCode周赛复盘] 第 354 场周赛20230716

一、本周周赛总结

  • T1 模拟。
  • T2 RUPQ 差分/树状数组。
  • T3 前后缀分解。
  • T4 双指针+trie(py负优化)。
    在这里插入图片描述

6889. 特殊元素平方和

6889. 特殊元素平方和

1. 题目描述

在这里插入图片描述

2. 思路分析

按题意模拟即可。

3. 代码实现

class Solution:
    def sumOfSquares(self, nums: List[int]) -> int:
        return sum(v*v for i,v in enumerate(nums,start=1) if len(nums)%i==0)

6929. 数组的最大美丽值

6929. 数组的最大美丽值

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 注意到值域很小,因此可以值域当下标,记录每个下标可以被访问多少次。
  • 那么其实是个区间+1。用差分可以搞。树状数组也可以。
  • 实现时,只需要对值域mn~mx处理即可,因为所有数都加相同的k,边界以外的次数一定不会超过边界(它们一定会路过边界)。

3. 代码实现

class Solution:
    def maximumBeauty(self, nums: List[int], k: int) -> int:
        mx = max(nums)
        d = [0]*(mx+2)
        for v in nums:
            x,y = max(0,v-k), min(mx,v+k)
            d[x] += 1
            d[y+1] -= 1 
            
        return max(accumulate(d))

6927. 合法分割的最小下标

6927. 合法分割的最小下标

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 前后缀分解。
  • 先计算出主元素x和它出现的次数y。那么前后缀的相同主元素只能是x。
  • 那么可以从头向后遍历,记录x的出现次数p,并计算后边剩余的次数y-p。
  • 找到第一个满足条件的下标即可。

3. 代码实现

class Solution:
    def minimumIndex(self, nums: List[int]) -> int:
        n = len(nums)
        cnt = Counter(nums)
        x,y = cnt.most_common(1)[0]
        p = 0
        for i,v in enumerate(nums):
            if v == x:
                p += 1 
                if p*2 > i+1 and (y-p)*2>(n-i-1):
                    return i
        return -1

6924. 最长合法子字符串的长度

6924. 最长合法子字符串的长度

1. 题目描述

在这里插入图片描述

2. 思路分析

  • 最长子段首先想到双指针/滑窗。
  • 枚举每个字母作为子段的右端点。尝试检查这个尾缀里是否再forbid里。
  • 由于forbid长度最多10,因此只需要暴力检查10次尾缀,找到最短那个fb尾缀,把左窗口挪过来,注意是l=j+1,因为要破坏这个非法单词。
  • 这样复杂度是n1010,每个字符要检查10次,每次检查复杂度是len(s)=10。

  • 可以用字典树trie优化成n*10。但是实测py果然还是切片+朴素set更快。
  • 对forbid逆序建树。
  • 枚举c为右端点时,也逆序向前组成字符串,然后去trie里判断是否存在这个单词。
  • 由于检查也是从右向左,同步检查,因此复杂度就是10。

3. 代码实现

朴素set

class Solution:
    def longestValidSubstring(self, word: str, forbidden: List[str]) -> int:
        fb = set(forbidden)
        l = ans = 0 
        for r,c in enumerate(word):            
            for j in range(r,max(l-1,r-10),-1):
                if word[j:r+1] in fb:
                    l = j+1
                    break
            # print(r,l)
            ans = max(ans, r-l+1)
        return ans                       

trie

class Solution:
    def longestValidSubstring(self, word: str, forbidden: List[str]) -> int:
        trie = {}
        for s in  forbidden:
            s = s[::-1]
            cur = trie 
            for c in s:
                if c not in cur:
                    cur[c] = {}
                cur = cur[c]
            cur['#'] = 1
        def query(s):
            cur = trie
            for i,c in enumerate(s,start=1):
                if c not in cur:
                    return 0 
                cur = cur[c]
                if '#' in cur:
                    return i 
            return 0
        l = ans = 0 
        for r,c in enumerate(word):     
            s = word[max(l,r-9):r+1] 
            i = query(s[::-1])
            if i:
                l = r - i+2
            ans = max(ans, r-l+1)
        return ans                 

参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值