[LeetCode周赛复盘] 第 313 场周赛20221002

一、本周周赛总结

二、 [Easy] 6192. 公因子的数目

链接: 6192. 公因子的数目

1. 题目描述

在这里插入图片描述

2. 思路分析

定级Easy。
计数gcd的因子即可。
如果ab值域上升,则可以在开方位置break。

3. 代码实现

class Solution:
    def commonFactors(self, a: int, b: int) -> int:
        s = gcd(a,b)
        ans = 1
        for i in range(2,s+1):
            if s%i == 0:
                ans += 1
        return ans

三、[Medium] 6193. 沙漏的最大总和

链接: 6193. 沙漏的最大总和

1. 题目描述

在这里插入图片描述

2. 思路分析

定级Medium。

  • 观察数据范围可以暴力。
  • 如果内层不是7的话,就需要二维前缀和。

3. 代码实现

class Solution:
    def maxSum(self, grid: List[List[int]]) -> int:
        m,n = len(grid),len(grid[0])
        ans = 0
        
        for i in range(m-2):
            for j in range(n-2):
                s=grid[i][j]+grid[i][j+1]+grid[i][j+2]+grid[i+1][j+1]+grid[i+2][j]+grid[i+2][j+1]+grid[i+2][j+2]
                if s > ans :
                    ans = s
        return ans

四、[Medium] 6194. 最小 XOR

链接: 6194. 最小 XOR

1. 题目描述

在这里插入图片描述

2. 思路分析

定级Medium。

  • 我们知道异或具有减法的性质,具体表现为:如果a^b,对a来说,b上的每一位对a的对应位造成的影响是:
    • 0保持:1^0 = 1; 0^0=0
    • 1改变:1^1=0; 0^1=1
  • 回到题目,num2的作用只是规定了答案的位1数量,因此我们直接计算n=num2.bit_count();然后用num1计算答案。
  • 让num1尽可能小,那就把它高位的1去掉,从上一步得知我们有n个1可以用。
  • 令m=num1.bit_count()
  • 显然如果n==m:可以正好把所有为对应上,异或值是0,答案就是num1本身。
  • 否则如果n<m:我们贪心的优先去安排对应高位,剩下低位的m-n个1不能安排上,只能置0。
    • 于是这里我们用lowbit技巧或者是汉明顿重量计算技巧x=x&(x-1)去掉最低位的m-n个1即可。
  • 如果n>m:显然num1上的每个1都有对应可以删掉了,还省n-m个1只能对应0,且会让异或值变大,那么我们贪心的放到num1原数中最低位的0的位置上即可。
    • 这里也有一个技巧,最低位的0的位置是x|(x+1)。

3. 代码实现

class Solution:
    def minimizeXor(self, num1: int, num2: int) -> int:
        n = num2.bit_count()
        # print(n)
        m = num1.bit_count()
        if n == m:
            return num1
        if n < m:
            for i in range(m-n):
                num1 = num1&(num1-1)
            return num1
        if n>m:            
            for _ in range(n-m):                
                num1|=num1+1
            return num1

五、[Hard] 6195. 对字母串可执行的最大删除数

链接: 6195. 对字母串可执行的最大删除数

1. 题目描述

在这里插入图片描述

2. 思路分析

定级Hard

  • 每次操作只能删除整串或者一个前缀。如果删除前缀,剩下的串是子问题。
  • DP。
  • 定义f[i]为删除s[i:]这个串可行的最大步数。
  • 转移:对于s[i:] 如果存在s[i:j]==s[j:j+j-i],那么f[i]=max(f[i],f[j]+1)
    • 级f[i] = max{f[j]+1|j>i 且s[i:j]==s[j:j+j-i]}
  • 初始:f[i]=1显然。
  • 剩下的问题就是如何在O(1)时间比较s[i:j]==s[j:j+j-i],这个裸做显然是O(n),这样总体复杂度就是O(n3)了。
  • 于是出现了今天的两篇模板,他们可以在O(1)时间比较两个字符串区间是否相等。[python刷题模板] 最长公共前缀LCP[python刷题模板] 字符串哈希

  • 以下代码是我在赛中用的刷表法,DP思想类似;
  • py占了切片的性能优势和时间范围容忍度,因此能过,这份代码实际是O(n3)的。
  • 但是实际表现O(n3)性能还胜于lcp和StringHash。
  • 正确O(n2)代码请看我今天整理的两篇模板。

3. 代码实现

class Solution:
    def deleteString(self, s: str) -> int:
        n = len(s)
        f = [0]*n
        
        for i in range(0,n-1):
            if i and not f[i]:continue
            for j in range(i+1,n):
                r = j+j-i
                if r > n:
                    break
                if s[i:j]==s[j:r]:
                    f[j] =max(f[j],f[i]+1)
        # print(f)
        return max(f)+1

六、参考链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值