leetcode 周赛 492,排名31

作者: | 更新日期:

递归

本文首发于公众号:天空的代码世界,微信号:tiankonguse

零、背景

这次比赛非常简单,30 分钟之内就写完了,可惜第二题错了一次,没进入前 25 名。

本场题型概览如下。
A 题:最小值。
B 题:前缀和。
C 题:分类贪心。
D 题:前缀和+递归。

最终排名:31。
代码仓库:详见 https://github.com/tiankonguse/leetcode-solutions

一、容量最小的箱子

题意:求大于等于 X 的最小值,多个时返回第一个。

思路:记录下当前最小值,遇到满足的更小的,则更新最小值。

二、找出最小平衡下标

题意:找一个下标,使得前缀和等于后缀积。

思路:预处理前缀和,从后到前计算后缀积,比大小。

小技巧1:后缀积大于前缀和时,直接结束循环。
小技巧2:使用__int128_t避免乘积溢出。
小技巧3:先使用double粗略判断大小,再使用long long精确判断大小。

三、将一个字符串排序的最小操作次数

题意:给一个字符串,每次可以选择一个子串进行排序,问最少需要多少次操作可以使得字符串有序。

思路:贪心

前缀子串定义:长度为n-1的前缀字符串,即不包含最后一个字符的子串。
后缀子串定义:长度为n-1的后缀字符串,即不包含第一个字符的子串。

如果已经有序,直接返回 0。
如果第一个字符就是最小值,后缀子串排序即可,直接返回 1。
如果最后一个字符就是最大值,前缀子串排序即可,直接返回 1。
否则最小值或者最大值在中间,前缀子串与后缀子串分别排序,直接返回 2。

特殊情况1:最值不在中间,即最小值在最后一个位置,最大值在第一个位置,中间不存在最值。
这时候,需要先选择后缀或者前缀排序一次,把最值调整到中间,然后再排序两次得到有序字符串。
答案为 3。

特殊情况2:字符串长度为 2,且不是有序。
此时,永远得不到答案。
返回 -1。

四、划分二进制字符串的最小费用

题意:给一个二进制字符串,每个子串有一个代价,长度是偶数时可以选择拆分为两个等长的子串,代价是两个子串的代价之和。问最小代价。
对于长度为 L 的二进制串中 1 的个数为 X 的代价定义为:X 为 0 时代价为 A,否则代价为 L * X * B

思路:递归

一开始可以预处理前缀和,从而可以快速计算出每个子串的代价。
拆分是可选择的,那就分别计算出两个答案,取最小值即可。

拆分不存在重复子问题,所以不需要缓存。
复杂度:O(n)

五、最后

这次比赛比较简单,第二题乘法会越界,需要使用 __int128_t
第三题贪心的分类情况比较多,不注意会遗漏。
第四题递归比较简单,不需要缓存。

《完》。

-EOF-

本文公众号:天空的代码世界
个人微信号:tiankonguse
公众号 ID:tiankonguse-code

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越