「这是我参与11月更文挑战的第 9 天,活动详情查看:2021最后一次更文挑战」
原题链接
908. 最小差值 I - 力扣(LeetCode) (leetcode-cn.com)
题目描述
给你一个整数数组 nums,请你给数组中的每个元素 nums[i] 都加上一个任意数字 x (-k <= x <= k),从而得到一个新数组 result 。
返回数组 result 的最大值和最小值之间可能存在的最小差值。
测试用例
示例 1:
输入:nums = [0,10], k = 2
输出:6
解释:result = [2,8]
示例 2:
输入:nums = [1,3,6], k = 3
输出:0
解释:result = [3,3,3] or result = [4,4,4]
参数限制
1 <= nums.length <= 100000 <= nums[i] <= 100000 <= k <= 10000
分析
在现有的数组上,为每一个数加上 [-k, k] 之间的值后,在新数组里找出最大最小项,计算他们的差值。在我们调整后每个数需要增加的最合适的值后,最大最小值的差值最小,题目大概是这么个意思,非常的绕
换个描述,在现有的数组上,找出他们的 max, min,算出差值 n,这个值是固定的。当在 [-k, k] 中分别选择两个数为 max, min 加上之后,他们的最小差值会是多少呢?
当 max-min > 2*k 时,这个最小的差值就是 2*k -(max-min)
当 max-min <= 2*k 时,这个最小差值就是 0
这道题最难的地方就是分析出上面两个公式
代码
最朴实的的方案,直接对数组进行升序排列,然后拿取开头的 min 结尾的 max,然后套公式返回值即可
var smallestRangeI = function(nums, k) {
nums = nums.sort((a, b) => a - b);
let diff = nums[nums.length - 1] - nums[0];
return diff <= 2 * k ? 0 : diff - 2 * k;
};
优化
优化掉排序的操作,使用 2 个变量 max, min,遍历数组时对变量进行更新,结束遍历后数组的最大最小值就出来了,其余操作照旧
var smallestRangeI = function(nums, k) {
let max = nums[0],
min = max;
nums.forEach(n => {
if (n > max) {
max = n;
} else if (n < min) {
min = n
}
})
let diff = max - min;
return diff <= 2 * k ? 0 : diff - 2 * k;
};
今天的力扣刷题就分享到这里,感谢大家的阅读~