题目
给定一个数列A,数列中相邻两项的差值的绝对值定义为“疯狂值”。任意排序这个数列,使得整个数列的“疯狂值”最大,输出这个最大值。
样例
输入
5 10 25 40 25
输出
100
解释:
当队列排列顺序是: 25-10-40-5-25时, 身高差绝对值的总和为15+30+35+20=100。可以有多种排列方案。
题解
首发于此:https://blog.nowcoder.net/n/aee5c4e3c14f48eeb678c6f839a6369b
很显然最终的排序结果必为交叉排布的,且符合[...低 高 低 高...]
的形式;
1.所以先对数列升序排序,很容易想到高的部分是数组的后一半,低的部分是数组的前一半。
2.观察[...低1, 高1, 低2, 高2...]
的形式,两两间差的绝对值之和=(高1-低1)+(高1-低2)+(高2-低2)
…
3.假设数组无穷多项,则显然高的那一半每个被加了两次,低的那一半每个被减了两次。
4.但由于数组必然不是无穷多项,必会有断开的。要断开的部分必然在升序数组的中间部分:
- 4.1 若总项数为偶数,则前一半的最后一个被多减去了一次、后一半的第一个被多加上了一次,需要进行修正。
- 4.2 若总项数为奇数,后一半的第一个依旧被多加上了一次。可以很清楚的知道前一半会被包在后一半中,即
[高...低 高 低 高...高]
,因此此时前一半没有被多减去一次,但高的一半的第二个又被多加上了一次,因此需要补正。
伪码
nums.sort()
res = (sum(nums[:mid]) - sum(nums[mid:])) * 2 -