给定一个整数数组 A,对于每个整数 A[i],我们可以选择 x = -K 或是 x = K,并将 x 加到 A[i] 中。
在此过程之后,我们得到一些数组 B。
返回 B 的最大值和 B 的最小值之间可能存在的最小差值。
示例 1:
输入:A = [1], K = 0 输出:0 解释:B = [1]
示例 2:
输入:A = [0,10], K = 2 输出:6 解释:B = [2,8]
示例 3:
输入:A = [1,3,6], K = 3 输出:3 解释:B = [4,6,3]
提示:
1 <= A.length <= 10000 0 <= A[i] <= 10000 0 <= K <= 10000题解:这个题目比较有趣,一开始想复杂了,后来你会发现,因为是找最大最小的情况,很容易通过枚举找到答案,我这里这样处理的,因为每个数字可以出现两种状态,+K或者-K。那么就可以枚举哪些数字可以作为最小值,然后找到此时的其他数字中最小的最大值。
这里需要注意,我们将原始数字从小到大排序后进行+K和-K处理,那么第一个数字+K一定是一个不可避免的最小值,也是最大的最小值。 比如:1 5 9 K=3 可以: 1->(-2,4) 5->(2,8) 9->(6,12) 会发现1对应的4是不可避免的最小值,也是所有最小值中的最大值,也就是说可以作为最小值的元素一定不会比4大。这个信息很重要。
这里为了更好理解,我画图说明: 上图是是对测试数据: 1 2 4 5 9 K=3 进行的绘图示意说明,每个数字对应上下两种结果,也就是每个数字可以选择上或者下的结果,这个图也很好说明了为啥第一个数字+K是所有可选最小数字中的最大值。 于是我们通过上图可以发现, 可以作为最小值的有:-2、-1、1、2、4(4是可以作为最小值的判定条件)。 那么我们就开始对这些最小值进行枚举找答案,发现取1为最小值时,也就是上图中第3个往下取1,那么前面的元素不能比1小,只能往上分别取4和5,此时左边有个最大的元素为5,那么此时右边呢?右边我们知道往下取的值都比1大,那么我们使右边的最大值尽可能小,于是右边取最后一个的往下取值的结果,为6,那么再进行判断,发现6比5大,于是不可抗拒的这里最大值为6,此时得到一个枚举的答案为6-1=5。 同理,设x表示此时的最小值,res表示答案: x=-2,左边最大没有,右边最小的最大为6,此时res=6-(-2)=8; x=-1,左边最大为4,右边最小的最大为6,此时res=max(4,6)-(-1)=7; x=1,左边最大为5,右边最小的最大为6,此时res=max(5,6)-(1)=5; x=2,左边最大为7,右边最小的最大为6,此时res=max(7,6)-(2)=5; x=4,左边没有了,此时第2、3、4个元素往下取的结果都小于4,不能往下取,只能往上取,此时得到最大值为8,而第5个元素往下取为6大于4,是可以取的,也就是从这个元素开始都可以往下取,那么此时右边最小的最大元素就是最右边的结果往下取,此时答案res=max(8,6)-4=4; 综合比较得到最小结果为4,为最终答案。
AC代码
class Solution { public: vector<int>B,C;//B表示往上取的结果,C表示往下取的结果 int smallestRangeII(vector<int>& A, int K) { B.clear(),C.clear(); sort(A.begin(),A.end()); for(int i=0;i<A.size();i++) { B.push_back(A[i]+K); C.push_back(A[i]-K); } int n=A.size()-1; int mi=abs(C[0]-C[n]); for(int i=1;i<=n;i++) { if(C[i]>B[0])break; mi=min(mi,abs(max(B[i-1],C[n])-C[i])); } int mx=-1e9; for(int i=1;i<=n;i++) { if(C[i]>B[0]) mx=max(mx,C[i]); else mx=max(mx,B[i]); } mi=min(mi,abs(mx-B[0])); return mi; } };