1. 程式人生 > >[LeetCode] Maximum Distance in Arrays 陣列中的最大距離

[LeetCode] Maximum Distance in Arrays 陣列中的最大距離

Given m arrays, and each array is sorted in ascending order. Now you can pick up two integers from two different arrays (each array picks one) and calculate the distance. We define the distance between two integers a and b to be their absolute difference |a-b|. Your task is to find the maximum distance.

Example 1:

Input: 
[[1,2,3],
 [4,5],
 [1,2,3]]
Output: 4
Explanation: 
One way to reach the maximum distance 4 is to pick 1 in the first or third array and pick 5 in the second array.

Note:

  1. Each given array will have at least 1 number. There will be at least two non-empty arrays.
  2. The total number of the integers in all the m
     arrays will be in the range of [2, 10000].
  3. The integers in the m arrays will be in the range of [-10000, 10000].

這道題給我們了一些陣列,每個陣列都是有序的,讓我們從不同的陣列中各取一個數字,使得這兩個數字的差的絕對值最大,讓我們求這個最大值。那麼我們想,既然陣列都是有序的,那麼差的絕對值最大的兩個數字肯定是分別位於陣列的首和尾,注意題目中說要從不同的陣列中取數,那麼即使某個陣列的首尾差距很大,也不行。博主最先考慮的是用堆來做,一個最大堆,一個最小堆,最大堆存每個陣列的尾元素,最小堆存每個陣列的首元素,由於最大的數字和最小的數字有可能來自於同一個陣列,所以我們在堆中存數字的時候還要存入當前數字所在的陣列的序號,最後我們其實要分別在最大堆和最小堆中各取兩個數字,如果最大的數字和最小的數字不在一個數組,那麼直接返回二者的絕對差即可,如果在的話,那麼要返回第二大數字和最小數字絕對差跟最大數字和第二小數字絕對差中的較大值,參見程式碼如下:

解法一:

class Solution {
public:
    int maxDistance(vector<vector<int>>& arrays) {
        priority_queue<pair<int, int>> mx, mn;
        for (int i = 0; i < arrays.size(); ++i) {
            mn.push({-arrays[i][0], i});
            mx.push({arrays[i].back(), i});
        }
        auto a1 = mx.top(); mx.pop();
        auto b1 = mn.top(); mn.pop();
        if (a1.second != b1.second) return a1.first + b1.first;
        return max(a1.first + mn.top().first, mx.top().first + b1.first);
    }
};

下面這種方法還是很不錯的,並沒有用到堆,而是用兩個變數start和end分別表示當前遍歷過的陣列中最小的首元素,和最大的尾元素,那麼每當我們遍歷到一個新的陣列時,只需計算新陣列尾元素和start絕對差,跟end和新陣列首元素的絕對差,取二者之間的較大值來更新結果res即可,參見程式碼如下:

解法二:

class Solution {
public:
    int maxDistance(vector<vector<int>>& arrays) {
        int res = 0, start = arrays[0][0], end = arrays[0].back();
        for (int i = 1; i < arrays.size(); ++i) {
            res = max(res, max(abs(arrays[i].back() - start), abs(end - arrays[i][0])));
            start = min(start, arrays[i][0]);
            end = max(end, arrays[i].back());
        }
        return res;
    }
};

參考資料: