[LeetCode 910] Smallest Range II
Given an array A
of integers, for each integer A[i]
we need to choose either x = -K
or x = K
, and add x
to A[i] (only once)
.
After this process, we have some array B
.
Return the smallest possible difference between the maximum value of B
and the minimum value of B
.
Example 1:
Input: A = [1], K = 0
Output: 0
Explanation: B = [1]
Example 2:
Input: A = [0,10], K = 2
Output: 6
Explanation: B = [2,8]
Example 3:
Input: A = [1,3,6], K = 3
Output: 3
Explanation: B = [4,6,3]
Note:
1 <= A.length <= 10000
0 <= A[i] <= 10000
0 <= K <= 10000
The key observation to solve this problem is that if A is already in sorted order, then it makes no sense to do -K on a smaller number and +K on a bigger number since this will only generate a bigger difference. So either we keep the relative differences among all elements the same by applying +K or -K to all, or we apply +K on some smaller numbers and -K on bigger numbers, hoping to find a better answer.
1. Sort A and set the current answer as A[n - 1] - A[0].
2. From A[0] to A[n - 2], use the current number A[i] as the split point, apply +K to A[0, i] and -K to A[i + 1, n - 1], compute the new max and min and update answer.
class Solution { public int smallestRangeII(int[] A, int K) { Arrays.sort(A); int n = A.length, minV = A[0], maxV = A[n - 1], ans = maxV - minV; for(int i = 0; i < n - 1; i++) { maxV = Math.max(A[i] + K, A[n - 1] - K); minV = Math.min(A[0] + K, A[i + 1] - K); ans = Math.min(ans, maxV - minV); } return ans; } }