You are given an integer array nums and an integer k.
For each index i where 0 <= i < nums.length, change nums[i] to be either nums[i] + k or nums[i] - k.
The score of nums is the difference between the maximum and minimum elements in nums.
Return the minimum score of nums after changing the values at each index.
Example 1:
Input: nums = [1], k = 0
Output: 0
Explanation: The score is max(nums) - min(nums) = 1 - 1 = 0.
Example 2:
Input: nums = [0,10], k = 2
Output: 6
Explanation: Change nums to be [2, 8]. The score is max(nums) - min(nums) = 8 - 2 = 6.
Example 3:
Input: nums = [1,3,6], k = 3
Output: 3
Explanation: Change nums to be [4, 6, 3]. The score is max(nums) - min(nums) = 6 - 3 = 3.
Constraints:
1 <= nums.length <= 104
0 <= nums[i] <= 104
0 <= k <= 104
最小差值 II。
給你一個整數陣列 nums,和一個整數 k 。對於每個下標 i(0 <= i < nums.length),將 nums[i] 變成 nums[i] + k 或 nums[i] - k 。
nums 的 分數 是 nums 中最大元素和最小元素的差值。
在更改每個下標對應的值之後,返回 nums 的最小 分數 。
思路
這道題是 908 題的版本二,題意跟 908 題稍有不同。在這道題裡,對於每個元素 nums[i]
而言,你必須做 +k 或 -k 的操作。這道題我參考了這個帖子,寫的很好,圖示也很清楚。
如果沒有 k,那麼這道題和 908 題一樣,直接求最大值和最小值差值即可。但是因為牽涉到 k 的操作了,而且我們要找的這個差值 (max - min) 需要儘可能小,所以基本的思路是要讓小的數字儘可能大(那就 + k),讓大的數字儘可能小(那就 - k)。但是在操作的過程中極有可能導致 min + k
比 max - k
要大。所以我們不能只考慮這兩個值,還要考慮中間的那些值。
所以對於任何一箇中間的 index i
而言,他左側的元素是 nums[0] 到 nums[i - 1]
;他右側的元素是 nums[i] 到 nums[n - 1]
。nums[0] 到 nums[i - 1]
都要 + k,nums[i] 到 nums[n - 1]
都要 - k。
這樣一來,
- 最大值就是
nums[n - 1] - k
和nums[i - 1] + k
的最大值 - 最小值就是
nums[i] - k
和nums[0] + k
的最小值
複雜度
時間O(nlogn) - sort
空間O(1)
程式碼
Java實現
class Solution {
public int smallestRangeII(int[] nums, int k) {
int n = nums.length;
Arrays.sort(nums);
int min = nums[0];
int max = nums[n - 1];
int res = max - min;
for (int i = 1; i < n; i++) {
max = Math.max(nums[i - 1] + k, nums[n - 1] - k);
min = Math.min(nums[0] + k, nums[i] - k);
res = Math.min(res, max - min);
}
return res;
}
}