第三次参加周赛,最后一题通过56/65个测试用例,时间超限
5561. 获取生成数组中的最大值(3分,通过率:2651/5482)
因为题目给出0<=n<=100,因此直接循环迭代
class Solution:
def getMaximumGenerated(self, n: int) -> int:
if n < 2:
return n
nums = [0 for i in range(n+1)]
nums[1] = 1
for i in range(2,n+1):
if i&1:
nums[i] = nums[i//2] + nums[i//2+1]
else:
nums[i] = nums[i//2]
return max(nums)
5562. 字符频次唯一的最小删除次数(4分,通过率:1926/4355)
PS:1<= s.length<=10^5
贪心算法
class Solution:
def minDeletions(self, s: str) -> int:
s_cnt = [0 for i in range(26)]
for _ in s:
s_cnt[ord(_)-ord('a')] += 1
s_cnt.sort(reverse=True)
cnt = 0
pre = s_cnt[0]
for _ in range(1,26):
if s_cnt[_]==0:
break
if s_cnt[_]>=pre:
pre = max(pre-1,0)
cnt += s_cnt[_] - pre
else:
pre = s_cnt[_]
return cnt
5563. 销售价值减少的颜色球(5分,通过率:477/3037)
题解中给出比较好的算法是贪心+二分查找
我用的是优化模拟,勉强AC
class Solution:
def maxProfit(self, inventory: List[int], orders: int) -> int:
dic = collections.defaultdict(lambda:0)
d = set([0])
dic[0] = 1
cnt = 0
for _ in inventory:
dic[_] += 1
d.add(_)
max_ = max(inventory)
num = dic[max_]
while(True):
max_s = 0
d.remove(max_)
for _ in d:
max_s = max(_,max_s)
num_s = dic[max_s]
to_m = (max_+max_s+1)*(max_-max_s)*num//2
if orders > (max_-max_s)*num:
orders -= (max_-max_s)*num
cnt += to_m
else:
s = orders//num
return ((max_*2-s+1)*num*s//2+ orders%num*(max_-s)+cnt)%1000000007
max_,num = max_s,num_s+num
二分查找法,是通过查找最后一次卖出时,球的价格x
最后返回的答案由两部分组成:
1.数量>x的颜色,肯定会减小到x,因此用等差数列求和
2.执行完第一步,仍有剩余orders,则这些orders一定会以x价格卖出
class Solution:
def maxProfit(self, inventory: List[int], orders: int) -> int:
l,r = 0,max(inventory)
while l <= r:
mid = (l + r) >> 1
total = sum(ai - mid for ai in inventory if ai > mid)
if total <= orders:
T = mid
r = mid - 1
else:
l = mid + 1
rest = orders - sum(ai - T for ai in inventory if ai > T)
ans = 0
for i in inventory:
if i > T:
ans += (T+1+i)*(i-T)>>1
return (ans + rest*T) % 1000000007
5564. 通过指令创建有序数组(6分,通过率:310/996)
这道题题解是用树状数组做的,我用的模拟+优化,还是卡在了最后几个样例的时间上
class Solution:
def createSortedArray(self, instructions: List[int]) -> int:
nums = set()
nums_cnt = collections.defaultdict(lambda:0)
cnt = 0
for _ in instructions:
sm=la=0
for num in nums:
if num < _:
sm += nums_cnt[num]
elif num > _:
la += nums_cnt[num]
nums.add(_)
if nums_cnt[_]>=1000000007:
nums_cnt[_] -= 1000000006
else:
nums_cnt[_] += 1
cnt += min(sm,la)
return cnt%1000000007