[LeetCode周赛复盘] 第 313 场周赛20221002
一、本周周赛总结
- 国庆快乐。
- 今天收获颇丰。
- 收获了两篇模板[python刷题模板] 最长公共前缀LCP、[python刷题模板] 字符串哈希
二、 [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. 对字母串可执行的最大删除数
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