例题1:最小差值I(力扣908)
题目链接:
力扣https://leetcode-cn.com/problems/smallest-range-i/
题目:
给你一个整数数组 nums,和一个整数 k 。
在一个操作中,您可以选择 0 <= i < nums 的任何索引 i 。将 nums[i] 改为 nums[i] + x ,其中 x 是一个范围为 [-k, k] 的整数。对于每个索引 i ,最多 只能 应用 一次 此操作。
nums 的 分数 是 nums 中最大和最小元素的差值。
在对nums中的每个索引最多应用一次上述操作后,返回 nums 的最低 分数 。
题目分析:
- 找出nums里的最大值和最小值
- 他们最多可以分别增加和减少k
- 那么差值就是 (max-min-2*k)的绝对值
代码:
class Solution {
public:
int smallestRangeI(vector<int>& nums, int k) {
//INT_MAX和INT_MIN分别为很大的数和很小的数,一般求最值时,可以这样初始化
int maxm = INT_MIN;
int minm = INT_MAX;
int n = nums.size();
for(int i=0;i<n;i++)
{
maxm = max(maxm,nums[i]);
minm = min(minm,nums[i]);
}
//防止maxm-minm-k*2为负数
return max(0,maxm-minm-k*2);
}
};
例题2: 最小差值II(力扣910)
题目链接:
力扣https://leetcode-cn.com/problems/smallest-range-ii/
题目:
给你一个整数数组 nums,和一个整数 k 。
对于每个下标 i(0 <= i < nums.length),将 nums[i] 变成 nums[i] + k 或 nums[i] - k 。
nums 的 分数 是 nums 中最大元素和最小元素的差值。
在更改每个下标对应的值之后,返回 nums 的最小 分数 。
题目分析 :
1.先对nums数组进行排序,方便计算差值的最值
2.再初始化差值为nums的最后一个元素和第一个元素的差值
3.最小的差值还可能出现在我们已经排序完后的相邻元素之间,前者+k,后者-k,遍历一遍求最小值即可
4.还要注意考虑边界的情况
代码:
class Solution {
public:
int smallestRangeII(vector<int>& nums, int k) {
sort(nums.begin(),nums.end());
int res = nums.back() - nums[0];
int n = nums.size();
for(int i=0;i<n-1;i++)
{
int minm = min(nums[0]+k, nums[i+1]-k);
int maxm = max(nums[n-1]-k, nums[i]+k);
res = min(res, maxm-minm);
}
return res;
}
};