774. Minimize Max Distance to Gas Station

Minimize Max Distance to Gas Station

On a horizontal number line, we have gas stations at positions stations[0], stations[1], ..., stations[N-1], where N = stations.length.

Now, we add K more gas stations so that D, the maximum distance between adjacent gas stations, is minimized.

Return the smallest possible value of D.

Example:
Input: stations = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], K = 9
Output: 0.500000

Note:

  1. stations.length will be an integer in range [10, 2000].
  2. stations[i] will be an integer in range [0, 10^8].
  3. K will be an integer in range [1, 10^6].
  4. Answers within 10^-6 of the true value will be accepted as correct.

方法1:
其实类似于[LeetCode]Split Array Largest Sum

相邻加油站间距的最大值为x, 用dp[i][j]表示有i个interval(i+1)个加油站,额外增加j个,然后对于所有的k

  • dp[i][j] = min(max(dp[i - 1][j - k], (stations[i] - stations[i - 1]) / (k + 1)))
  • base case: dp[i][0] = max(stations[1] - stations[0], ..., stations[i] - stations[i - 1])

dp[i-1][j-k] j-k个附加的加油站分布在前i-1个区间,于是剩下的stations[i] - stations[i - 1]共享k个

for all k

class Solution {
public:
    int splitArray(vector& nums, int m) {
        int len = nums.size(), sum = 0;
        //dp[i][j] represents minimum largest sum by dividing first i characters into j subarrays
        //dp[i][j] = min(max(dp[k][j - 1], sum(k + 1, i)))
        //base case: dp[i][1] = presum[i] - 0(since we need to get dp[k][j - 1] when calculate dp[i][j]), dp[i][0] = INT_MAX, dp[0][i] = INT_MAX;
        vector> dp(len + 1, vector(m + 1, INT_MAX));
        vector preSums(1, 0);
        for(auto& num : nums){sum += num;preSums.push_back(sum);};
        for(int i = 0; i < len; ++i)
        {
            dp[i + 1][1] = preSums[i + 1] - preSums[0];
            for(int j = 2; j <= min(i + 1, m); ++j)
            {
                for(int k = i; k >= j - 1; --k)
                {
                    dp[i + 1][j] = min(max(dp[k][j - 1], preSums[i + 1] - preSums[k]), dp[i + 1][j]);
                }
            }
        }
        return dp[len][m];
    }
};

方法2:
对于搜索类的题目,如果我们知道答案ans所在的区间[lo, hi],并且给定一个值y,我们有比较效率的算法可以验证y是否是ans的上/下界,那么通常binary search都是值得考虑的算法。这一题也是同样,显然我们知道答案是在[max(array[i]), sum(0, n - 1)]区间中,并且给定y,我们有O(n)的算法可以验证y是否是答案ans的上/下界:

  • 我们从头开始切分array,每一次我们找到当前区间和小于y的最大值所对应的区间,如果最后切分的区间数d > m,那么我们知道y是ans的下界,因为y可以更大从而d可以更小,也就是代表ans >= y
  • 如果d <= m,显然我们应该减小y让其能切分更多的subarray,也就是说y是ans的上界,ans <= y

根据以上条件我们就可以采用binary search的解法来解决这道题,时间复杂度O(n * log(sum)),常数空间,代码如下:

class Solution {
    public double minmaxGasDist(int[] st, int K) {
        int count = 0, N = st.length;
        double left = 0, right = st[N-1] - st[0], mid;
        
        while(left+1e-6K) right = mid;
            else left = mid;
        }
        return right;
    }
}

你可能感兴趣的:(774. Minimize Max Distance to Gas Station)