Medium

题目描述

给你 m 个数组,每个数组都已按 升序 排列。

你可以从两个不同的数组中各选一个整数(每个数组选择一个),然后计算它们的距离。我们定义两个整数 a 和 b 之间的距离为它们差的绝对值 |a - b|。

返回最大距离。

示例 1:

输入:arrays = [[1,2,3],[4,5],[1,2,3]]
输出:4
解释:一种达到最大距离 4 的方法是从第一个数组或第三个数组中选择 1,从第二个数组中选择 5。

示例 2:

输入:arrays = [[1],[1]]
输出:0

提示:

  • m == arrays.length
  • 2 <= m <= 10^5
  • 1 <= arrays[i].length <= 500
  • -10^4 <= arrays[i][j] <= 10^4
  • arrays[i] 按升序排列
  • 所有数组中最多有 10^5 个整数

解题思路

解题思路

这道题要求从两个不同数组中各选一个数,使得它们的距离最大。由于每个数组都是升序排列的,我们只需要考虑每个数组的最大值和最小值。

核心思想: 最大距离一定出现在某个数组的最小值与另一个数组的最大值之间。

贪心策略:

  1. 维护当前遍历过的所有数组的全局最小值和全局最大值
  2. 对于当前数组,计算其最小值与之前数组最大值的距离,以及其最大值与之前数组最小值的距离
  3. 更新全局最小值、最大值和最大距离

算法流程:

  1. 初始化全局最小值和最大值为第一个数组的最小值和最大值
  2. 从第二个数组开始遍历,对于每个数组:
    • 计算当前数组最小值与全局最大值的距离
    • 计算当前数组最大值与全局最小值的距离
    • 更新最大距离
    • 更新全局最小值和最大值

这种方法避免了嵌套循环,时间复杂度为 O(m),其中 m 是数组个数。

代码实现

class Solution {
public:
    int maxDistance(vector<vector<int>>& arrays) {
        int minVal = arrays[0][0];
        int maxVal = arrays[0].back();
        int maxDist = 0;
        
        for (int i = 1; i < arrays.size(); i++) {
            int currMin = arrays[i][0];
            int currMax = arrays[i].back();
            
            maxDist = max(maxDist, max(abs(currMax - minVal), abs(maxVal - currMin)));
            
            minVal = min(minVal, currMin);
            maxVal = max(maxVal, currMax);
        }
        
        return maxDist;
    }
};
class Solution:
    def maxDistance(self, arrays: List[List[int]]) -> int:
        min_val = arrays[0][0]
        max_val = arrays[0][-1]
        max_dist = 0
        
        for i in range(1, len(arrays)):
            curr_min = arrays[i][0]
            curr_max = arrays[i][-1]
            
            max_dist = max(max_dist, max(abs(curr_max - min_val), abs(max_val - curr_min)))
            
            min_val = min(min_val, curr_min)
            max_val = max(max_val, curr_max)
        
        return max_dist
public class Solution {
    public int MaxDistance(IList<IList<int>> arrays) {
        int minVal = arrays[0][0];
        int maxVal = arrays[0][arrays[0].Count - 1];
        int maxDist = 0;
        
        for (int i = 1; i < arrays.Count; i++) {
            int currMin = arrays[i][0];
            int currMax = arrays[i][arrays[i].Count - 1];
            
            maxDist = Math.Max(maxDist, Math.Max(Math.Abs(currMax - minVal), Math.Abs(maxVal - currMin)));
            
            minVal = Math.Min(minVal, currMin);
            maxVal = Math.Max(maxVal, currMax);
        }
        
        return maxDist;
    }
}
var maxDistance = function(arrays) {
    let minVal = arrays[0][0];
    let maxVal = arrays[0][arrays[0].length - 1];
    let maxDist = 0;
    
    for (let i = 1; i < arrays.length; i++) {
        const currMin = arrays[i][0];
        const currMax = arrays[i][arrays[i].length - 1];
        
        maxDist = Math.max(maxDist, Math.max(Math.abs(currMax - minVal), Math.abs(maxVal - currMin)));
        
        minVal = Math.min(minVal, currMin);
        maxVal = Math.max(maxVal, currMax);
    }
    
    return maxDist;
};

复杂度分析

复杂度类型
时间复杂度O(m)
空间复杂度O(1)

其中 m 是数组的个数。我们只需要遍历一次所有数组,每次操作都是常数时间,因此时间复杂度为 O(m)。只使用了常数个额外变量,空间复杂度为 O(1)。