LeetCode 624. 数组列表中的最大距离
题目描述


题意分析
从两个不同的升序数组中各取一个整数,使两数差的绝对值最大。限制在于来源数组必须不同,所以不能直接取全部元素的最大值减最小值,它们可能来自同一个数组。
每个数组已经有序,只需关注首项与末项;中间值不会比端点产生更大的跨数组距离。
解法:一次扫描维护全局最小/最大
核心思路
[!blue]
从左到右处理数组,用globalMin保存此前所有数组的最小首项,globalMax保存最大末项。处理当前数组时,读取它的curMin和curMax,只需考虑两种方向。如果当前数组提供较大数,最优配对是
curMax - globalMin;如果此前数组提供较大数,最优配对是globalMax - curMin。这两个方向已经覆盖绝对值的两种情况,不需要再遍历内部元素或单独取绝对值。必须先用这两个候选更新答案,再把当前首尾并入全局极值。计算候选时,全局极值只来自此前数组,因此与当前元素配对一定满足来源不同;如果先更新,就可能错误地选择当前数组自己的首尾。
任意两个不同数组总有一个先出现、一个后出现。扫描到后者时,前者已经包含在历史极值中,它们能产生的最佳距离一定被本轮候选覆盖。保留此前答案并逐轮更新,就得到全部数组对的最大距离。
解题步骤
- 用第一个数组的首尾初始化此前极值。
- 从第二个数组开始,读取当前首尾。
- 计算两个跨数组方向的候选。
- 随后更新全局极值,继续扫描。
答案初始为零,因为距离不会为负。单元素数组的首尾相同,仍按同一流程处理;多个数组中的值全相同时,结果保持为零。
代码实现
class Solution {
public int maxDistance(List<List<Integer>> arrays) {
int globalMin = arrays.get(0).get(0);
List<Integer> first = arrays.get(0);
int globalMax = first.get(first.size() - 1);
int answer = 0;
for (int i = 1; i < arrays.size(); i++) {
List<Integer> arr = arrays.get(i);
int curMin = arr.get(0);
int curMax = arr.get(arr.size() - 1);
// 先与此前数组的极值配对,确保两端来自不同数组。
answer = Math.max(answer, curMax - globalMin);
answer = Math.max(answer, globalMax - curMin);
// 本轮候选算完后,才将当前数组纳入前缀极值。
globalMin = Math.min(globalMin, curMin);
globalMax = Math.max(globalMax, curMax);
}
return answer;
}
}
func maxDistance(arrays [][]int) int {
globalMin := arrays[0][0]
globalMax := arrays[0][len(arrays[0])-1]
answer := 0
for i := 1; i < len(arrays); i++ {
arr := arrays[i]
curMin := arr[0]
curMax := arr[len(arr)-1]
// 先与此前数组的极值配对,确保两端来自不同数组。
if curMax-globalMin > answer {
answer = curMax - globalMin
}
if globalMax-curMin > answer {
answer = globalMax - curMin
}
// 本轮候选算完后,才将当前数组纳入前缀极值。
if curMin < globalMin {
globalMin = curMin
}
if curMax > globalMax {
globalMax = curMax
}
}
return answer
}
复杂度分析
- 时间复杂度:$O(m)$,m 为数组数,按常数时间读取数组端点计。
- 空间复杂度:$O(1)$。
关键点总结
[!green]
- 先配对再更新,顺序保证来源不同。
- 两个方向都要比较,当前数组可能提供最小值,也可能提供最大值。
- 绝对距离非负,答案初始化零是合法下界。
易错点总结
[!yellow]
- 先更新极值:可能选中当前数组自己的首尾。
- 只算一个方向:漏掉此前最大值与当前最小值的组合。
- 从第一个数组就开始配对:会把同数组内部距离算进答案。
- 遍历全部内部元素找极值:没有利用已有排序。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 121. 买卖股票的最佳时机 | 简单 | 同样扫描时保留此前极值,但本题必须先用当前数组与旧极值比较,再更新,避免两值来自同一数组。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!