基本思路
我们先把数组排个序,题目要求求最小差值,那么就必须是大数-$k$,小数+$k$,这样才能尽可能地减小差值。
那么哪些是所谓的’大数’呢?我们可以设置一个分割点$i$,即$i$为序列中最后一个需要+$k$的下标,在$i$之前的数是小数,在$i$之后的数是大数。那么整个序列的最大值就是$max(A.back()-k , A[i] + k)$,最小值就是$min(A[0]+k , A[i+1]-k)$
为什么分割点之前的数都是小数呢?
首先我们令$i$是序列中最后一个需要+$k$的下标,使得$A[i]$要+$k$,其次$A[0]$一定要+$k$,$A.back()$一定要-$k$,我们设$j < i$,由于$A[j]+k < A[i]+k$,$A[j]-k$要么$> A[0]+k$,此时对结果没有影响,要么$A[j]-k < A[0]+k$,此时使得结果变大了,不可取,所以我们干脆使得$A[j]+k$,这样对结果没有影响,所以对于$j < i$,$A[j]$必须+$k$。
为什么分割点之后的数都是大数呢?
我们令$i$是序列中最后一个需要+$k$的下标,使得$A[i]$要+$k$,所以之后的都是大数了。
分割点不存在怎么办?
不可能,分割点最小是0,此时的差值是$A.back()-A[0] - 2*k$。
代码
1 | class Solution { |
