[LeetCode] 910. Smallest Range II 最小區間之二



Given an array A of integers, for each integer A[i] we need to choose either x = -K or x = K, and add x to A[i] (only once).html

After this process, we have some array B.git

Return the smallest possible difference between the maximum value of B and the minimum value of B.github

Example 1:數組

Input: A = [1], K = 0
Output: 0
Explanation: B = [1]

Example 2:flex

Input: A = [0,10], K = 2
Output: 6 Explanation: B = [2,8]

Example 3:this

Input: A = [1,3,6], K = 3
Output: 3
Explanation: B = [4,6,3]

Note:code

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



這道題是以前那道 Smallest Range I 的拓展,那道題說的是每一個數字能夠加上 [-K, K] 範圍內的任意一個數字,這道題說是每一個數字必須加上K或者 —K,都是問新數組的最大值最小值之間的差值最小是多少。這兩個條件有顯著的區別,對於前一道題來講,很是的 flexible,由於能夠加上 [-K, K] 範圍內的任意一個數字,就是說也能夠加上0,從而數字保持不變,那麼只須要對原數組的最大值最小值進行修改便可,而這道題全部數字都強制要進行修改,則只考慮最大值最小值顯然是不對的。來想一想爲何不能直接對最小值加K,最大值減K,而後算差值。來看題目中的例子3,A = [1,3,6], K = 3,對最小值加K,獲得4,對最大值減K,獲得3,相減獲得 -1,但其實是不對的,由於中間的3也要進行加減操做,只能變成0或6,這樣至關於改變了新數組的最大值最小值,最終算下來的結果應該是3。博主其實也嘗試了暴力搜索法,即將原數組中的每一個數字進行加K和減K,把獲得的兩個新數字放到一個新數組中,最後遍歷新數組,找出最大值最小值並作差,結果超時了 Time Limit Exceeded!即使這只是一道 Medium 的題目,仍然不準咱們用如此 Naive 的方法。只能另闢蹊徑了。htm

若是不考慮數字修改,那麼原數組的最大值最小值之間的差值就是所求,這裏能夠看成結果 res 的初始值。因爲每一個數字都須要加K或者減K,爲了使得新數組的最大值最小值的差值最小,應該儘可能使原數組中的較小的數字加K,較大的數字減K,因此最好是先給原數組排個序,而後在數組的某個位置i爲界限,將原數組分爲兩段,前面全部的數字都加K,後面全部的數字都減K。則前半段 [0, i] 中的最大值是 A[i]+K,最小值是 A[0]+K,後半段 [i+1, n-1] 範圍內的最大值是 A[n-1]-K,最小值是 A[i+1]-K,因此整個數組的最大值是 A[i]+K 和 A[n-1]-K 中的較大值,最小值是 A[0]+K 和 A[i+1]-K 中的較小值,兩者作差就是可能的結果了,遍歷全部的i,用每次計算出的差值來更新結果 res 便可,參見代碼以下:blog


class Solution {
public:
    int smallestRangeII(vector<int>& A, int K) {
        sort(A.begin(), A.end());
        int n = A.size(), res = A[n - 1] - A[0];
        int left = A[0] + K, right =  A[n - 1] - K;
        for (int i = 0; i < n - 1; ++i) {
            int high = max(right, A[i] + K);
            int low = min(left, A[i + 1] - K);
            res = min(res, high - low);
        }
        return res;
    }
};



Github 同步地址:leetcode

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



相似題目:

Smallest Range I



參考資料:

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

https://leetcode.com/problems/smallest-range-ii/discuss/173377/C%2B%2BJavaPython-Add-0-or-2-*-K

https://leetcode.com/problems/smallest-range-ii/discuss/173389/simple-C%2B%2B-solution-with-explanation



LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索