我们有一个n个正整数的数组。可接受的举措是将元素增加1并将其中一个邻居减少1.
最终数组中的最小值和最大值应至少相差1.这样做的最小移动次数是多少?
例如,如果初始数组是{5,6,4,1,10},则答案为5,最终数组可能为{5,5,5,5,6}。
答案 0 :(得分:2)
我们可以使用Divide and Conquer解决这个问题。
我们知道所有元素的最终值必须是数组中所有元素的AVERAGE。如果平均值不是整数,那么我们可以定义两个值 - MAX和MIN,这样MAX是平均值的上限,MIN是平均值的下限。 (http://en.wikipedia.org/wiki/Floor_and_ceiling_functions)
现在将数组分成2个相等的部分。 [0-n / 2]和[n / 2 +1到n-1]。如果n是奇数,则前半部分会变小,但这并不重要。
对于每一半,计算所有元素的平均值。这个平均HAS等于MAX或MIN。如果不是,则必须根据需要提高或降低此平均值。
现在要注意的一点是,子阵列的平均值不能通过仅涉及该子阵列内的元素的操作来修改。因此,任何改变都需要在第n / 2和第n + 2 + 1个元素之间进行操作。
另一点需要注意的是,如果一个子阵列的平均值小于所需值,则另一个子阵列的平均值大于所需值。
因此,可以在两个中间元素之间轻松地进行适当的操作。
现在将每个子阵列分成两部分,然后重复该过程。
[注意:计算子阵列平均值所需的重复求和运算可以通过使用区间树http://en.wikipedia.org/wiki/Interval_tree进行更新以及求和运算的对数时间。