Leetcode 517
这是一段困难题,我也想了很绕,然后弄清楚其中的原理。
首先,我们可以很轻易地用 O n 时间算出平均每个洗衣机应该有的衣物,如果这个数不是整数,就返回 -1。
其次,我们要注意题目条件:一个洗衣机一次只能转移一件衣服,但是可以同时接收多件衣服。
然后我们考虑一下「传输速度」:一个有富余的洗衣机,转移到一个有缺漏的洗衣机,需要几步?
假设我们现在处于洗衣机 i, 现在往左寻找。如果我们找到一个有缺漏的洗衣机就停止,设这个洗衣机为 j。
[-1 0 0 +1 0 0 +3]
[j i]
其实只需要一步,因为每个洗衣机同时往左边传递一个衣服,就可以完成从 i 到 j 的衣物数量传递。
通过上面的分析,我们发现,衣服的转移次数,至少是【洗衣机衣物富余数量的最大值】,因为洗衣机每次只能向外转移一件衣物,但是它可以立刻转移到一个缺漏处。
这也是为什么官方题解的max函数里面,有一个 max(..., ..., num),其中num是富余/缺漏数量。
接下来我们分析为什么前缀和绝对值也是需要被放到max中考量的点。
考虑前缀和 presum > 0。这说明,就算把前缀当中所有的坑填平,那么还是会有富余。例如:
2 -1 3 0 -4
当我们遍历到 3 的时候,我们发现前缀和是 4。那么我们有没有可能两个富余的洗衣机都传递过去呢?模拟一下就会发现不行:
1 0 2 0 -3
0 0 2 0 -2
0 0 1 0 -1
0 0 0 0 0
因此前缀和如果大于 0,那么大于 0 的这部分是不能同时传递的。每次传递,只能减少掉最远端的衣物富余,中间的富余洗衣机因为进一出一,还是会没法消耗掉衣物。
前缀和 presum < 0 的情况同理,但是这时候要取 abs。
所以我们得到每次遍历需要做的事情就是计算 ans = max(ans, 前缀和绝对值, 当前洗衣机的富余数量)