[LeetCode] 908. Smallest Range I 最小区间


Given an array `A` of integers, for each integer `A[i]` we may choose any `x` with `-K <= x <= K`, and add `x` to `A[i]`.

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: 0 Explanation: B = [3,3,3] or B = [4,4,4]

Note:

  1. 1 <= A.length <= 10000
  2. 0 <= A[i] <= 10000
  3. 0 <= K <= 10000

这道题说是给了一个非负数的数组,和一个非负数K,说是数组中的每一个数字都可以加上 [-K, K] 范围内的任意一个数字,问新数组的最大值最小值之间的差值最小是多少。这道题的难度是 Easy,理论上应该是可以无脑写代码的,但其实很容易想的特别复杂。本题的解题标签是 Math,这种类型的题目基本上就是一种脑筋急转弯的题目,有时候一根筋转不过来就怎么也做不出来。首先来想,既然是要求新数组的最大值和最小值之间的关系,那么肯定是跟原数组的最大值最小值有着某种联系,原数组的最大值最小值我们可以很容易的得到,只要找出了跟新数组之间的联系,问题就能迎刃而解了。题目中说了每个数字都可以加上 [-K, K] 范围内的数字,当然最大值最小值也可以,如何让二者之间的差值最小呢?当然是让最大值尽可能变小,最小值尽可能变大了,所以最大值 mx 要加上 -K,而最小值 mn 要加上K,然后再做减法,即 (mx-K)-(mn+K) = mx-mn+2K,这就是要求的答案啦,参见代码如下:
解法一:
class Solution {
public:
    int smallestRangeI(vector<int>& A, int K) {
        int mx = A[0], mn = A[0];
        for (int num : A) {
            mx = max(mx, num);
            mn = min(mn, num);
        }
        return max(0, mx - mn - 2 * K);
    }
};

我们也可以使用 STL 自带的求最大值最小值的函数,从而一行搞定碉堡了~
解法二:
class Solution {
public:
    int smallestRangeI(vector<int>& A, int K) {
        return max(0, *max_element(A.begin(), A.end()) - K - (*min_element(A.begin(), A.end()) + K));
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/908


类似题目:

Smallest Range II


参考资料:

https://leetcode.com/problems/smallest-range-i/

https://leetcode.com/problems/smallest-range-i/discuss/173512/C%2B%2B-1-liner

https://leetcode.com/problems/smallest-range-i/discuss/173367/C%2B%2BJavaPython-Check-Max-Min


[LeetCode All in One 题目讲解汇总(持续更新中...)](https://www.cnblogs.com/grandyang/p/4606334.html)
posted @ 2019-08-07 22:20  Grandyang  阅读(2119)  评论(0编辑  收藏  举报
Fork me on GitHub