一、题目描述
给定 m
个数组,每个数组都已经按照升序排好序了。
现在你需要从两个不同的数组中选择两个整数(每个数组选一个)并且计算它们的距离。两个整数 a
和 b
之间的距离定义为它们差的绝对值 |a-b|
。
返回最大距离。
示例 1:
输入:[[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
个整数。
二、解题思路
- 初始化两个变量,
globalMin
和globalMax
,用于记录所有数组中的最小值和最大值。 - 遍历每个数组,对于每个数组:
- 取出该数组的第一个元素(最小值)和最后一个元素(最大值)。
- 更新
globalMin
和globalMax
。 - 计算当前数组的最小值与
globalMax
的差的绝对值,以及当前数组的最大值与globalMin
的差的绝对值,并更新最大距离。
- 继续遍历剩余的数组,每次都更新最大距离,直到遍历完所有数组。
三、具体代码
import java.util.List;
public class Solution {
public int maxDistance(List<List<Integer>> arrays) {
// 初始化为第一个数组的最小值和最大值
int globalMin = arrays.get(0).get(0);
int globalMax = arrays.get(0).get(arrays.get(0).size() - 1);
int maxDist = 0;
// 从第二个数组开始遍历
for (int i = 1; i < arrays.size(); i++) {
List<Integer> array = arrays.get(i);
int currentMin = array.get(0);
int currentMax = array.get(array.size() - 1);
// 更新最大距离
maxDist = Math.max(maxDist, Math.max(Math.abs(globalMax - currentMin), Math.abs(globalMin - currentMax)));
// 更新全局最小值和最大值
globalMin = Math.min(globalMin, currentMin);
globalMax = Math.max(globalMax, currentMax);
}
return maxDist;
}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
-
初始化
globalMin
和globalMax
需要从第一个数组中获取最小值和最大值,这需要 O(1) 的时间复杂度,因为每个数组已经是排序的,最小值和最大值分别位于数组的第一个和最后一个位置。 -
接下来,代码进入一个循环,该循环遍历剩余的数组。假设有 m 个数组,那么循环将执行 m-1 次(因为第一个数组已经在初始化时处理了)。
-
在每次循环迭代中,我们执行以下操作:
- 获取当前数组的最小值和最大值,这需要 O(1) 的时间复杂度。
- 计算当前数组的最小值与
globalMax
的差的绝对值,以及当前数组的最大值与globalMin
的差的绝对值,并更新最大距离,这需要 O(1) 的时间复杂度。 - 更新
globalMin
和globalMax
,这也需要 O(1) 的时间复杂度。
由于这些操作在每次循环迭代中都是常数时间复杂度,因此整个循环的时间复杂度是 O(m)。
综上所述,整个函数的时间复杂度是 O(m),其中 m 是数组的数量。
2. 空间复杂度
-
在整个算法中,我们只使用了几个整数变量(
globalMin
,globalMax
,maxDist
,currentMin
,currentMax
),无论输入数组的大小如何,这些变量的数量都是固定的。 -
我们没有使用任何依赖于输入大小的数据结构,如数组或列表。
因此,算法的空间复杂度是 O(1),即常数空间复杂度。这意味着算法使用的空间不随输入数组的大小而变化。
五、总结知识点
-
类定义:
public class Solution
:定义了一个公共类Solution
。
-
方法定义:
public int maxDistance(List<List<Integer>> arrays)
:定义了一个公共方法maxDistance
,它接受一个类型为List<List<Integer>>
的参数arrays
并返回一个int
类型的结果。
-
基本数据类型:
int
:用于定义整数变量。
-
列表和泛型:
List<List<Integer>>
:使用了泛型列表,表示一个列表的列表,其中每个元素都是Integer
类型的列表。
-
循环结构:
for
循环:用于遍历列表中的每个元素。
-
条件判断和数学运算:
Math.max()
:用于计算两个数的最大值。Math.abs()
:用于计算一个数的绝对值。Math.min()
:用于计算两个数的最小值。
-
列表操作:
arrays.get(i)
:用于获取列表arrays
中索引为i
的元素。array.get(0)
和array.get(array.size() - 1)
:用于获取列表array
的第一个和最后一个元素。
-
变量赋值:
- 使用
=
运算符进行变量赋值。
- 使用
-
方法调用:
- 调用
Math
类的静态方法max()
和min()
。
- 调用
-
返回值:
- 使用
return
语句返回方法的结果。
- 使用
-
访问列表元素:
- 使用
list.get(index)
访问列表中指定索引的元素。
- 使用
-
链式调用:
- 在一行代码中连续调用多个方法,如
Math.max(Math.abs(globalMax - currentMin), Math.abs(globalMin - currentMax))
。
- 在一行代码中连续调用多个方法,如
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。