题目地址:632. 最小区间
You have k
lists of sorted integers in ascending order. Find the smallest range that includes at least one number from each of the k
lists.
We define the range [a,b]
is smaller than range [c,d]
if b-a < d-c
or a < c
if b-a == d-c
.
- Example 1:
Input: [[4,10,15,24,26], [0,9,12,20], [5,18,22,30]]
Output: [20,24]
Explanation:
List 1: [4, 10, 15, 24,26], 24 is in range [20,24].
List 2: [0, 9, 12, 20], 20 is in range [20,24].
List 3: [5, 18, 22, 30], 22 is in range [20,24].
Note:
- The given list may contain duplicates, so ascending order means >= here.
- 1 <= k <= 3500
- -10^5 <= value of elements <= 10^5.
解题思路:
先看
4,10,15,24,26
0, 9,12,20
5,18,22,30
因为每个数组中必须有一个数字包含在其中,一开始我们取每个数组中的第一个数字
*4*,10,15,24,26
*0*, 9,12,20
*5*,18,22,30
4,0,5
最小的是0
,最大值是5
区间是5-0=5
把第一个最小区间5的坐标记录下来就是[0,5]
去掉最小的值,然后最小值所在的数组向后取一位即
*4*,10,15,24,26
0, *9*,12,20
*5*,18,22,30
4,9,5
最小的是4
,最大值是9
区间是9-4=5
最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,*10*,15,24,26
0, *9*,12,20
*5*,18,22,30
10,9,5
最小的是5
,最大值是10
区间是10-5=5
最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,*10*,15,24,26
0, *9*,12,20
5,*18*,22,30
10,9,18
最小的是9
,最大值是18
区间是18-9=9
,因为9>5
不符合规则,最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,*10*,15,24,26
0, 9,*12*,20
5,*18*,22,30
10,12,18
最小的是10
,最大值是18
区间是18-10=8
,因为8>5
不符合规则,最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,10,*15*,24,26
0, 9,*12*,20
5,*18*,22,30
15,12,18
最小的是12
,最大值是18
区间是18-12=6
,因为6>5
不符合规则,最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,10,*15*,24,26
0, 9,12,*20*
5,*18*,22,30
15,20,18
最小的是15
,最大值是20
区间是20-15=5
,最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,10,15,*24*,26
0, 9,12,*20*
5,*18*,22,30
24,20,18
最小的是18
,最大值是24
区间是24-18=6
,因为6>5
不符合规则,最小区间不变还是5,所以去掉最小的值,然后最小值所在的数组向后取一位即
4,10,15,*24*,26
0, 9,12,*20*
5,18,*22*,30
24,20,22
最小的是20
,最大值是24
区间是24-20=4
,因为4<5
符合规则,最小区间变更为4,把最小区间4的坐标记录下来就是[20,24]
,这时继续向后走,由于最小值是20
而20
所在的数组已经走到了结尾,不能继续走,再走就不能满足每个数组中必须有一个数包含在其中.
所以返回最小区间[20,24
参考代码:
class Solution {
public int[] smallestRange(List> nums) {
// 里面存储的是行列数据位置,优先级是列中数据大小
PriorityQueue q = new PriorityQueue<>(Comparator.comparingInt(o -> nums.get(o[0]).get(o[1])));
int max = Integer.MIN_VALUE, start = 0, end = Integer.MAX_VALUE;
// 先让每个数组中的第一个数进入 q
for (int i = 0; i < nums.size(); i++) {
q.offer(new int[]{i, 0});
max = Math.max(max, nums.get(i).get(0));
}
while (q.size() == nums.size()) {
// 取出最小的元素获得到行列信息
int e[] = q.poll(), row = e[0], col = e[1];
// 比较,如果符合条件就更新最小区间信息
if (end - start > max - nums.get(row).get(col)) {
start = nums.get(row).get(col);
end = max;
}
// 防止越界
if (col + 1 < nums.get(row).size()) {
q.offer(new int[]{row, col + 1});
max = Math.max(max, nums.get(row).get(col + 1));
}
}
return new int[]{start, end};
}
}