forked from gouthampradhan/leetcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSmallestRange.java
86 lines (76 loc) · 2.89 KB
/
SmallestRange.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package two_pointers;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.PriorityQueue;
/**
* Created by gouthamvidyapradhan on 23/01/2018.
* 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.
For Java users, please note that the input type has been changed to List<List<Integer>>. And after you reset the
code template, you'll see this point.
Solution O(n log m) where m is the total number of lists and n in the total elements in all the list combined.
*/
public class SmallestRange {
class MinIndex{
int i, j;
MinIndex(int i, int j){
this.i = i;
this.j = j;
}
}
/**
* Main method
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception{
List<List<Integer>> list = new ArrayList<>();
List<Integer> row1 = Arrays.asList(4,10,15,24,26);
List<Integer> row2 = Arrays.asList(0,9,12,20);
List<Integer> row3 = Arrays.asList(5,18,22,30);
list.add(row1);
list.add(row2);
list.add(row3);
int[] R = new SmallestRange().smallestRange(list);
System.out.println(R[0] + " " + R[1]);
}
public int[] smallestRange(List<List<Integer>> nums) {
PriorityQueue<MinIndex> pq = new PriorityQueue<>((o1, o2) ->
Integer.compare(nums.get(o1.i).get(o1.j), nums.get(o2.i).get(o2.j)));
int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
for(int i = 0, l = nums.size(); i < l; i ++){
min = Math.min(min, nums.get(i).get(0));
max = Math.max(max, nums.get(i).get(0));
pq.offer(new MinIndex(i, 0));
}
if(min == max) return new int[]{min, max};
int ansMin = min, ansMax = max;
while(true){
MinIndex minIndex = pq.poll();
if(minIndex.j + 1 >= nums.get(minIndex.i).size()){
return new int[]{ansMin, ansMax};
}
int next = nums.get(minIndex.i).get(minIndex.j + 1);
max = Math.max(max, next); //update max if any
pq.offer(new MinIndex(minIndex.i, minIndex.j + 1));
min = nums.get(pq.peek().i).get(pq.peek().j); //new minimum
if((max - min) < (ansMax - ansMin)){
ansMax = max;
ansMin = min;
}
}
}
}