成绩:40min 前两题 第三题死在超时
第一题:
5561. 获取生成数组中的最大值
给你一个整数 n
。按下述规则生成一个长度为 n + 1
的数组 nums
:
nums[0] = 0
nums[1] = 1
- 当
2 <= 2 * i <= n
时,nums[2 * i] = nums[i]
- 当
2 <= 2 * i + 1 <= n
时,nums[2 * i + 1] = nums[i] + nums[i + 1]
返回生成数组 nums
中的 最大 值。
示例 1:
输入:n = 7 输出:3 解释:根据规则: nums[0] = 0 nums[1] = 1 nums[(1 * 2) = 2] = nums[1] = 1 nums[(1 * 2) + 1 = 3] = nums[1] + nums[2] = 1 + 1 = 2 nums[(2 * 2) = 4] = nums[2] = 1 nums[(2 * 2) + 1 = 5] = nums[2] + nums[3] = 1 + 2 = 3 nums[(3 * 2) = 6] = nums[3] = 2 nums[(3 * 2) + 1 = 7] = nums[3] + nums[4] = 2 + 1 = 3 因此,nums = [0,1,1,2,1,3,2,3],最大值 3
示例 2:
输入:n = 2 输出:1 解释:根据规则,nums[0]、nums[1] 和 nums[2] 之中的最大值是 1
示例 3:
输入:n = 3 输出:2 解释:根据规则,nums[0]、nums[1]、nums[2] 和 nums[3] 之中的最大值是 2
提示:
0 <= n <= 100
比较简单,但写时需要注意的是,对数组的更改应该是按位的,不能先执行一遍偶数项再执行奇数项,后者将导致结果完全错误。
class Solution: def getMaximumGenerated(self, n: int) -> int: if n == 0: return 0 nums = [0 for i in range(n + 1)] nums[0] = 0 nums[1] = 1 i = 1 while 2 * i <= n or 2 * i + 1 <= n: nums[2 * i] = nums[i] if 2 * i + 1 <= n: nums[2 * i + 1] = nums[i] + nums[i + 1] i += 1 return max(nums)
第二题:
5562. 字符频次唯一的最小删除次数
如果字符串 s 中 不存在 两个不同字符 频次 相同的情况,就称 s 是 优质字符串 。
给你一个字符串 s,返回使 s 成为 优质字符串 需要删除的 最小 字符数。
字符串中字符的 频次 是该字符在字符串中的出现次数。例如,在字符串 "aab" 中,'a' 的频次是 2,而 'b' 的频次是 1 。
示例 1:
输入:s = "aab"
输出:0
解释:s 已经是优质字符串。
示例 2:
输入:s = "aaabbbcc"
输出:2
解释:可以删除两个 'b' , 得到优质字符串 "aaabcc" 。
另一种方式是删除一个 'b' 和一个 'c' ,得到优质字符串 "aaabbc" 。
示例 3:
输入:s = "ceabaacb"
输出:2
解释:可以删除两个 'c' 得到优质字符串 "eabaab" 。
注意,只需要关注结果字符串中仍然存在的字符。(即,频次为 0 的字符会忽略不计。)
提示:
1 <= s.length <= 105
s 仅含小写英文字母
本题也没有难度,先用set找出字符串中不重复的字符,然后按位统计字符出现的次数存入list,在list中将重复的项-1,直至该项在list中只出现一次为止,统计-1执行的次数。
注意:当被-1的项为0时,我们忽略该项。
class Solution: def minDeletions(self, s: str) -> int: s2 = set(s) s3 = list(s2) num_occur = [] cnt = 0 for i in s3: num_occur.append(s.count(i)) for i in range(len(num_occur)): while (num_occur[i] != 0) and (num_occur.count(num_occur[i]) > 1): num_occur[i] -= 1 cnt += 1 return cnt
第三题:
5563. 销售价值减少的颜色球
你有一些球的库存 inventory ,里面包含着不同颜色的球。一个顾客想要 任意颜色 总数为 orders 的球。
这位顾客有一种特殊的方式衡量球的价值:每个球的价值是目前剩下的 同色球 的数目。比方说还剩下 6 个黄球,那么顾客买第一个黄球的时候该黄球的价值为 6 。这笔交易以后,只剩下 5 个黄球了,所以下一个黄球的价值为 5 (也就是球的价值随着顾客购买同色球是递减的)
给你整数数组 inventory ,其中 inventory[i] 表示第 i 种颜色球一开始的数目。同时给你整数 orders ,表示顾客总共想买的球数目。你可以按照 任意顺序 卖球。
请你返回卖了 orders 个球以后 最大 总价值之和。由于答案可能会很大,请你返回答案对 109 + 7 取余数 的结果。
示例 1:
输入:inventory = [2,5], orders = 4
输出:14
解释:卖 1 个第一种颜色的球(价值为 2 ),卖 3 个第二种颜色的球(价值为 5 + 4 + 3)。
最大总和为 2 + 5 + 4 + 3 = 14 。
示例 2:
输入:inventory = [3,5], orders = 6
输出:19
解释:卖 2 个第一种颜色的球(价值为 3 + 2),卖 4 个第二种颜色的球(价值为 5 + 4 + 3 + 2)。
最大总和为 3 + 2 + 5 + 4 + 3 + 2 = 19 。
示例 3:
输入:inventory = [2,8,4,10,6], orders = 20
输出:110
示例 4:
输入:inventory = [1000000000], orders = 1000000000
输出:21
解释:卖 1000000000 次第一种颜色的球,总价值为 500000000500000000 。 500000000500000000 对 109 + 7 取余为 21 。
提示:
1 <= inventory.length <= 105
1 <= inventory[i] <= 109
1 <= orders <= min(sum(inventory[i]), 109)
用了最简单的思路去解,即每次找出价值最大的,将该价值累加到value,然后对列表中该项-1,对要取的球的数量-1,直到要取的球的数量为0.
这种思路简单的代价就是超时,如执行
class Solution: def maxProfit(self, inventory: List[int], orders: int) -> int: if len(inventory) == 1 and orders == inventory[0]: return ((inventory[0] // 2) * (inventory[0] + 1) % (10 ** 9 + 7)) value = 0 while orders > 0: value += max(inventory) inventory[inventory.index(max(inventory))] -= 1 orders -= 1 return value % (10 ** 9 + 7)
苦思冥想很久,最终决定优化if中return的公式。比赛期间优化的最终结果如下:
class Solution: def maxProfit(self, inventory: List[int], orders: int) -> int: if len(inventory) == 1: return (((inventory[0] - orders // 2) * 2 + 1) * (orders // 2)) % (10 ** 9 + 7) value = 0 while orders > 0: value += max(inventory) inventory[inventory.index(max(inventory))] -= 1 orders -= 1 return value % (10 ** 9 + 7)
但执行时结果错误。
本周周赛经历就到此为止了,赶紧去第三题评论区蹲题解。