class Solution:
def smallestRangeI(self, nums, k):
return max(0, max(nums) - min(nums) - 2 * k)
class Solution {
public:
int smallestRangeI(vector<int>& nums, int k) {
int mn = *min_element(nums.begin(), nums.end());
int mx = *max_element(nums.begin(), nums.end());
return max(0, mx - mn - 2 * k);
}
};
class Solution {
public int smallestRangeI(int[] nums, int k) {
int mn = Integer.MAX_VALUE, mx = Integer.MIN_VALUE;
for (int num : nums) {
mn = Math.min(mn, num);
mx = Math.max(mx, num);
}
return Math.max(0, mx - mn - 2 * k);
}
}
var smallestRangeI = function(nums, k) {
let mn = Math.min(...nums);
let mx = Math.max(...nums);
return Math.max(0, mx - mn - 2 * k);
};
You are given an array of integers nums
and an integer k
. For every element in nums
, you are allowed to increase or decrease it by at most k
(each element can be changed independently and by any value between -k
and k
, inclusive). After performing these operations, your goal is to find the smallest possible difference between the maximum and minimum elements in the array.
k
in either direction.
At first glance, it might seem that we need to try all possible combinations of increasing or decreasing each element by up to k
and then find the minimum range. However, this quickly becomes infeasible for large arrays due to the huge number of possibilities.
Instead, let's think about the problem more strategically. If we want to minimize the difference between the maximum and minimum elements, we should try to bring the largest element down and the smallest element up as much as possible. Since every element can be shifted by at most k
, the maximum element can be decreased by k
and the minimum can be increased by k
.
The key insight is that the minimum possible range after all operations is the original range minus 2 * k
(since both ends can move by k
), but it cannot be less than zero (if the numbers can overlap or cross).
min
) and maximum value (max
) in the array.max - min
.k
and the maximum value can be decreased by k
.min + k
and the new maximum is at most max - k
.(max - k) - (min + k) = (max - min) - 2 * k
.0
.max(0, (max - min) - 2 * k)
.This approach is efficient, requiring only a single pass to find the min and max, and then a simple calculation.
Let's take nums = [1, 3, 6]
and k = 3
.
1
, the maximum is 6
.6 - 1 = 5
.1
by 3
, it becomes 4
.6
by 3
, it becomes 3
.max(0, 6 - 1 - 2*3) = max(0, 5 - 6) = max(0, -1) = 0
.0
.
Another example: nums = [0, 10]
, k = 2
.
6
.O(2^n)
(where n
is the length of nums
), which is infeasible.O(n)
time), and use O(1)
extra space.
To solve the "Smallest Range I" problem, we avoid brute-force by realizing that maximizing the increase of the smallest number and the decrease of the largest number gives the best result. The minimal possible range is the original range minus 2 * k
, but it cannot go below zero. This approach is both efficient and elegant, requiring only min/max calculations and a simple formula.