632.Smallest-Range-Covering-Elements-from-K-Lists
632. Smallest Range Covering Elements from K Lists
题目地址
https://leetcode.com/problems/smallest-range-covering-elements-from-k-lists/
题目描述
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
-105 <= value of elements <= 105.
代码
Approach #1 Priority Queue + Next Array
Time: O(n * log m) && Space: O(m)
class Solution {
public int[] smallestRange(int[][] nums) {
int minx = 0;
int miny = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int[] next = new int[nums.length];
boolean flag = true;
PriorityQueue<Integer> min_queue = new PriorityQueue<Integer>((i, j) -> nums[i][next[i]] - nums[j][next[j]]);
for (int i = 0; i < nums.length; i++) {
min_queue.offer(i);
max = Math.max(max, nums[i][0]);
}
for (int i = 0; i < nums.length && flag; i++) {
for (int j = 0; j < nums[i].length && flag; j++) {
int min_i = min_queue.poll();
if (max - nums[min_i][next[min_i]] < miny - minx) {
minx = nums[min_i][next[min_i]];
miny = max;
}
next[min_i]++;
if (next[min_i] == nums[min_i].length) {
flag = false;
break;
}
min_queue.offer(min_i);
max = Math.max(max, nums[min_i][next[min_i]]);
}
}
return new int[] {minx, miny};
}
}
Approach #2 Two Pointer [TLE]
Time complexity : O(nm) Space complexity : O(m)
next[i]
refers to the element which needs to be considered next in the (i-1)th
list.
class Solution {
public int[] smallestRange(int[][] nums) {
int minx = 0;
int miny = Integer.MAX_VALUE;
int[] next = new int[nums.length];
boolean flag = true;
for (int i = 0; i < nums.length && flag; i++) {
for (int j = 0; j < nums[i].length && flag; j++) {
int min_i = 0;
int max_i = 0;
for (int k = 0; k < nums.length; k++) {
if (nums[k][next[k]] < nums[min_i][next[min_i]]) {
min_i = k;
}
if (nums[k][next[k]] > nums[max_i][next[max_i]]) {
max_i = k;
}
}
if (nums[max_i][next[max_i]] - nums[min_i][next[min_i]] < miny - minx) {
minx = nums[min_i][next[min_i]];
miny = nums[max_i][next[max_i]];
}
next[min_i]++;
if (next[min_i] == nums[min_i].length) {
flag = false;
}
}
}
return new int[] {minx, miny};
}
}
Approach #3 maxHeap & minHeap
class Solution {
public int[] smallestRange(List<List<Integer>> nums) {
PriorityQueue<int[]> min = new PriorityQueue<>(1, new Comparator<int[]>(){
public int compare(int[] n1, int[] n2) {
return nums.get(n1[0]).get(n1[1]) - nums.get(n2[0]).get(n2[1]);
}
});
// PriorityQueue<int[]> min = new PriorityQueue<>((n1, n2) -> nums.get(n1[0]).get(n1[1]) - nums.get(n2[0]).get(n2[1]));
PriorityQueue<int[]> max = new PriorityQueue<>(1, new Comparator<int[]>() {
public int compare(int[] n1, int[] n2) {
return nums.get(n2[0]).get(n2[1]) - nums.get(n1[0]).get(n1[1]);
}
});
for (int i = 0; i < nums.size(); i++) {
int[] tmp = new int[]{i, 0}; // index -> next index
min.offer(tmp);
max.offer(tmp);
}
int[] res = new int[] {Integer.MIN_VALUE, Integer.MAX_VALUE};
while (min.size() == nums.size()) {
int[] m1 = max.peek();
int[] m2 = min.poll();
if ((long)nums.get(m1[0]).get(m1[1]) - (long)nums.get(m2[0]).get(m2[1]) < (long)res[1] - (long)res[0]) {
res[0] = nums.get(m2[0]).get(m2[1]);
res[1] = nums.get(m1[0]).get(m1[1]);
}
if (m2[1] + 1 < nums.get(m2[0]).size()) {
int[] m3 = new int[]{m2[0], m2[1] + 1};
min.offer(m3);
max.offer(m3);
max.remove(m2);
}
}
return res;
}
}
Last updated