疯狂队列:排序以最大化数组两两间差的绝对值之和

文章目录

问题

https://www.nowcoder.com/questionTerminal/306ce234874a4cb1880e2f4310d8ce13

排序以最大化数组两两间差的绝对值之和,即求 max ⁡ ( ∣ a 1 − a 2 ∣ + ∣ a 2 − a 3 ∣ + ⋯   ) \max(|a_1-a_2|+|a_2-a_3|+\cdots) max(a1a2+a2a3+)

解决

参考:https://blog.nowcoder.net/n/aee5c4e3c14f48eeb678c6f839a6369b

最后的形式肯定是交错的,比如 ⋯ s m a l l 1 , b i g 1 , s m a l l 2 , b i g 2 , ⋯ \cdots small_1,big_1, small_2, big_2, \cdots small1,big1,small2,big2,,结果为: ∣ b i g 1 − s m a l l 1 ∣ + ∣ b i g 1 − s m a l l 2 ∣ + ∣ b i g 2 − s m a l l 2 ∣ + ∣ b i g 2 − s m a l l 3 ∣ + ⋯ |big_1-small_1|+|big_1-small_2|+|big_2-small_2|+|big_2-small_3|+\cdots big1small1+big1small2+big2small2+big2small3+,因此序列无限长时,相当于把序列排序后平分两份,两份差的2倍就是结果。

但是现实场景往往不行,需要分类讨论奇数长度与偶数长度。

如果是偶数长度, s m a l l 1 , b i g 1 , s m a l l 2 , b i g 2 small_1,big_1,small_2,big_2 small1,big1,small2,big2,结果为 ∣ b i g 1 − s m a l l 1 ∣ + ∣ b i g 1 − s m a l l 2 ∣ + ∣ b i g 2 − s m a l l 2 ∣ = 2 b i g 1 − 2 s m a l l 2 + b i g 2 − s m a l l 1 |big_1-small_1|+|big_1-small_2|+|big_2-small_2|=2big_1-2small_2+big_2-small_1 big1small1+big1small2+big2small2=2big12small2+big2small1,因此按上述差的2倍方式算,会多算一个 b i g 2 − s m a l l 1 big_2-small_1 big2small1,我们需要差最大,即该值最小,所以多算了 big 序列中最小的与 small 序列中最大的差,所以是减小 big 序列中最小的,加上 small 序列中最大的。

如果是奇数长度, b i g 1 , s m a l l 1 , b i g 2 , s m a l l 2 , b i g 3 big_1,small_1,big_2,small_2,big_3 big1,small1,big2,small2,big3,因为分开时取下界,所以 small 序列更短。结果为 ∣ b i g 1 − s m a l l 1 ∣ + ∣ b i g 2 − s m a l l 1 ∣ + ∣ b i g 2 − s m a l l 2 ∣ + ∣ b i g 3 − s m a l l 2 ∣ = 2 b i g 2 − 2 s m a l l 2 − 2 s m a l l 1 + b i g 1 + b i g 3 |big_1-small_1|+|big_2-small_1|+|big_2-small_2|+|big_3-small_2|=2big_2-2small_2-2small_1+big_1+big_3 big1small1+big2small1+big2small2+big3small2=2big22small22small1+big1+big3,因此按上述差的2倍方式算,多加了 big 序列中的两个,所以减去big序列中最小的两个即可。

python代码:

def solution(nums):
    nums = sorted(nums)
    mid = len(nums) // 2
    flag = len(nums)%2 == 0
    res = 2 * (sum(nums[mid:]) - sum(nums[:mid])) - nums[mid]
    if flag:
        res += nums[mid-1]
    else:
        res -= nums[mid+1]
    return res

如果用全排列2进行枚举往往会超时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值