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, 前缀和绝对值, 当前洗衣机的富余数量)

 

         

 

posted on 2021-09-29 14:09  Ricochet!  阅读(20)  评论(0编辑  收藏  举报