[LeetCode周赛复盘] 第 100 场双周赛20230318
一、本周周赛总结
- 补,这次双周赛比较简单,没打有点亏。
- T1 分类讨论。
- T2 双指针田忌赛马或者计数。
- T3 排序模拟。
- T4 二分。
二、 [Easy] 6323. 将钱分给最多的儿童
链接: 6323. 将钱分给最多的儿童
1. 题目描述
2. 思路分析
按题意模拟即可。
3. 代码实现
class Solution:
def distMoney(self, money: int, children: int) -> int:
if children == 1 and money == 4:
return -1
if money < children:
return -1
m = money - children
ans,mod = divmod(m,7)
if ans == 0:
return 0
if ans == children - 1:
if mod == 3:
return ans - 1
return ans
if ans == children:
return ans - int(mod>0)
if ans > children:
return children - 1
return ans
三、[Medium] 6324. 最大化数组的伟大值
链接: 6324. 最大化数组的伟大值
1. 题目描述
2. 思路分析
- 排序后最大化匹配,给尽可能多的数找一个比它大的数。
- 双指针找就行。
- 手玩一下发现,瓶颈在于最多的那个数,假设有c个,排序后只需要错位c个位置,就能保证剩下的都是符合要求的。
- 假设排序后数组是112233344。发现有3个3
- 令大的数组删去前边3个数,即左移3位。那么这个数组剩下的数都是满足>上边的数组。
3. 代码实现
、class Solution:
def maximizeGreatness(self, nums: List[int]) -> int:
# nums.sort(reverse=True)
a = sorted(nums)
n = len(a)
l = 0
ans = 0
for v in a:
if a[l] < v:
ans += 1
l += 1
return ans
四、[Medium] 6351. 标记所有元素后数组的分数
1. 题目描述
2. 思路分析
- 直接带着下标排序,然后记录vis即可。
- 我一定是疯了还用堆做。
3. 代码实现
class Solution:
def findScore(self, nums: List[int]) -> int:
marked = set()
ans = 0
for v,i in sorted([(v,i) for i,v in enumerate(nums)]):
if i not in marked:
ans += v
marked.add(i-1)
marked.add(i+1)
return ans
五、[Hard] 6325. 修车的最少时间
链接: 6325. 修车的最少时间
1. 题目描述
2. 思路分析
- 花的时间越多,越可能修完车。
- 假设时间x能修完车,大于x的时间都能修完。
- 假设时间y修不完,小于y的时间都修不完。
- 因此有单调性,可以二分。
- 实现时,发现值域很小,因此可以计数,单词扫描的时间可以降低。
3. 代码实现
class Solution:
def repairCars(self, ranks: List[int], cars: int) -> int:
cnt = Counter(ranks)
s = lambda t: sum(floor((t // r) ** 0.5) * c for r, c in cnt.items())
return bisect_left(range(min(cnt) * cars * cars), cars, key=s)