leetcode 第 294 场算法比赛

作者: | 更新日期:

昨晚睡得晚,再次翻车,有想法,但是比较混乱。

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

零、背景

这次比赛最后一题有点难度,我很喜欢。

但是我思路比较混乱,比赛期间没做出来,比较遗憾。

复盘一下是因为公式太复杂。
而我只是纸上简单画一下,大脑里推导出公式,没有在纸上写出完整的公式。
最终导致反复在大脑中推导公式,竟然来了四五轮。

赛后,耐下心来纸上写出完整的公式,一下就通过了。

一、字母在字符串中的百分比

题意:问指定的字符出现的频率。

思路:循环统计,除以总个数即可。

二、装满石头的背包的最大数量

题意:有若干容量有限的背包和石头,问最多可以装满多少个背包。

思路:背包排序,从小到大装即可。

三、表示一个折线图的最少线段数

题意:给若干坐标,问从头到尾连线,有多少线段。

思路:按横坐标轴排序,然后判断相邻三点是否在一条直线上即可。

PS:昨晚睡得晚,网页上修改完代码后,本地没修改,导致这道题我错了四次。

四、巫师的总力量和

题意:给一个数组,求所有子数组的魔法值之和。
子数组魔法值定义:子数组之和乘以子数组的最小值。

思路:有O(n^2)个子数组,数据范围是10^5,显然不能暴力计算。

所以我们需要思考,如何才能在 O(n) 或者 O(n log(n)) 时间复杂度内计算出答案。

要降低复杂度,必然涉及到不同子数组之间有公共部分,可以进行合并计算。

显然,公共部分就是最小值,最小值相等的子数组,可以累积求和,最后再乘以这个最小值。

所以问题转化为了,枚举每个位置的值,快速求出以这个位置为最小值的子数组之和的和。

对于这个子问题,其实纸上画画也不难,先求出所有当前最小值为后缀的和,然后是后面一个的和,直到最后一个。
之后就是合并通用项,最终可以推导出一个公式来。

推导过程如下图:

注意实现:对于相等的两个,我们可以定义左边的更小。
即有子数组覆盖两个最小值时,这个子数组划分到左边的最小值。

五、最后

这次比赛第三题太不细心了,第四题没有在纸上推导出公式,只在大脑里推导,吃了大亏。

经验总结就是,以后要细心,以后要先在纸上推导出公式。

加油,算法人。

《完》

-EOF-

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

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

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

tiankonguse +
穿越