LeetCode周赛#103 Q3 Smallest Range II (枚举)

题目来源:https://leetcode.com/contest/weekly-contest-103/problems/smallest-range-ii/

问题描述

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).

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


Note:

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

------------------------------------------------------------

题意

给定一个数列A和一个正整数K,规定数列B的生成方式为:A中的每个数必须加上K或减去K得到B中相应元素。问如此得到所有的数列B,最大值和最小值之差最小是多少?

------------------------------------------------------------

思路

本题实际上就是要解决得到数列B的过程中,数列A中哪些数需要+K,哪些数需要-K的问题。本蒟蒻想了很久想不出来这个问题,最后参考了这篇博文【leetcode】910. Smallest Range II才会的。在此感谢这位博主啦。

如果直接枚举,复杂度为O(2^N)。考虑利用单调性降低枚举的复杂度。首先将A排序,不妨设A升序排列,记作A+。对于A+,如果希望最小化最大值与最小值之差,有如下两条性质:

1. 若A+[i]需要+K,则A+[i]之前的数也都需要+K

2. 若A+[i]需要-K,则A+[i]之后的数也都需要-K

根据上述两条性质,我们总能在A+中找到一个i, 是的A+[i]以及A+[i]之前的数都+K,A+[i]之后的数都-K,这样,枚举的复杂度就降低到了O(N). 另排序的复杂度为O(NlogN),故总复杂度为O(NlogN).

------------------------------------------------------------

代码

class Solution {
public:
    const int inf = 0x3f3f3f3f;
    
    int smallestRangeII(vector<int>& A, int K) {
        int minv = inf, maxv = -inf, i, len = A.size(), left, right, ans = inf;
        sort(A.begin(), A.end());
        for (i=0; i<len; i++)
        {
            if (i == len-1)
            {
                ans = min(A[len-1] - A[0], ans);
            }
            else
            {
                right = max(A[i] + K, A[len-1] - K);
                left = min(A[i+1] - K, A[0] + K);
                ans = min(ans, abs(right - left));
            }
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/da_kao_la/article/details/82842832