[LeetCode周赛复盘] 第 321 场周赛20221127
- 一、本周周赛总结
- 二、 [Easy] 6245. 找出中枢整数
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 三、[Medium]6246. 追加字符以获得子序列
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 四、[Medium] 6247. 从链表中移除节点
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 五、[Hard] 6248. 统计中位数为 K 的子数组
- 1. 题目描述
- 2. 思路分析
- 3. 代码实现
- 六、参考链接
一、本周周赛总结
- 好难啊,但是怎么过的人这么多。
- T1暴力或者公式。
- T2子序列双指针。
- T3链表题。
- T4前缀和+哈希表,两种做法。
二、 [Easy] 6245. 找出中枢整数
链接: 6245. 找出中枢整数
1. 题目描述
2. 思路分析
按题意模拟即可。
3. 代码实现
class Solution:
def pivotInteger(self, n: int) -> int:
s = (1+n)*n//2
p = 0
for i in range(1,n+1):
p += i
if p == s - p + i:
return i
return -1
三、[Medium]6246. 追加字符以获得子序列
链接: 6246. 追加字符以获得子序列
1. 题目描述
2. 思路分析
按题意模拟即可。
- 和判断子序列很像,直接双指针扫描即可。
- 看s最多能匹配t前缀多长。
3. 代码实现
class Solution:
def appendCharacters(self, s: str, t: str) -> int:
m,n = len(s),len(t)
j = 0
for i,c in enumerate(s):
if j<n and t[j] == c:
j += 1
if j == n:
return 0
# print(n,j)
return n - j
四、[Medium] 6247. 从链表中移除节点
链接: 6247. 从链表中移除节点
1. 题目描述
2. 思路分析
- 比赛时直接转数组然后dp做的,其实可以递归,下面给出递归写法。
3. 代码实现
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def removeNodes(self, head: Optional[ListNode]) -> Optional[ListNode]:
"""最后的结果,head一定是最大的,且后缀同样满足这个属性,因此可以递归
"""
if not head :return head
nxt = self.removeNodes(head.next)
if not nxt:return head
if nxt.val > head.val :return nxt
head.next = nxt
return head
五、[Hard] 6248. 统计中位数为 K 的子数组
链接: 6248. 统计中位数为 K 的子数组
1. 题目描述
2. 思路分析
- 比赛时写了比较麻烦的左右前缀和,还wa一次。
- 注意题目,数据是1-n的排列。意味着k一定只出现一次。找到k的位置p。所有子数组都要包含p。
- k如果是中位数的话,这个数组里小于k的数less一定等于大于k的数big,或less+1=big(偶数长度情况)
- 于是我们从p出发向两侧扩展数组,使用前缀和统计两边子数组less和big的大小计数。
- 于是就可以用乘法原理乘起来即可。
- 更简单的方法可以转换,把原数组转化为:小于k记-1,大于k记1,等于k记10**6。
- 题目转化成有多少个子数组,子数组和=106或106+1。
- 这题就是普通的前缀和+哈希表。
3. 代码实现
转化为前缀和+哈希表
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
n = len(nums)
a = []
mx =10**6
for v in nums:
if v < k:
a.append(-1)
elif v>k:
a.append(1)
else:
a.append(mx)
s = 0
d = Counter()
d[0] = 1
ans = 0
for i,v in enumerate(a):
s += v
ans += d[s-mx]+d[s-mx-1]
d[s] += 1
return ans
左右前缀和
class Solution:
def countSubarrays(self, nums: List[int], k: int) -> int:
n = len(nums)
d = {(0,0,0):1}
p = nums.index(k)
ans = 1
l,r = Counter(),Counter()
s = 0
for j in range(p+1,n):
s += 1 if nums[j]>k else -1
r[s] += 1
ans += r[0]+r[1]
s = 0
for j in range(p-1,-1,-1):
s += 1 if nums[j]>k else -1
l[s] += 1
ans += l[0]+l[1]
ans += l[0]*r[0]
for i in range(1,n):
ans += l[i]*r[-i]+l[i]*r[-i+1]+r[i]*l[-i]+r[i]*l[-i+1]
return ans