Merge k Sorted Intervals
Merge_K_sorted interval lists into one sorted interval list. You need to merge overlapping intervals too.
Example
Given
[
[(1,3),(4,7),(6,8)],
[(1,2),(9,10)]
]
Return
[(1,3),(4,8),(9,10)]
class Element implements Comparable<Element> {
int i, j;
Interval interval;
Element(int i, int j, Interval interval) {
this.i = i;
this.j = j;
this.interval = interval;
}
@Override
public int compareTo(Element o) {
return this.interval.start - o.interval.start;
}
}
Code1
private List<Interval> mergeHelper_v1_minHeap(List<List<Interval>> intervals) {
PriorityQueue<Element> minHeap = new PriorityQueue<>();
for (int i = 0; i < intervals.size(); i++) {
List<Interval> list = intervals.get(i);
if (list != null && !list.isEmpty()) {
minHeap.offer(new Element(i, 0, list.get(0)));
}
}
List<Interval> merge = new ArrayList<>();
Interval last = null;
while (!minHeap.isEmpty()) {
Element cur = minHeap.poll();
if (last == null || last.end < cur.interval.start) {
merge.add(cur.interval);
last = cur.interval;
} else {
last.end = Math.max(last.end, cur.interval.end);
}
if (cur.j + 1 < intervals.get(cur.i).size()) {
cur.j++;
cur.interval = intervals.get(cur.i).get(cur.j);
minHeap.offer(cur);
}
}
return merge;
}
Code2
private List<Interval> mergeHelper_v2_Divide_Conquer(List<List<Interval>> intervals, int low, int high) {
if (low >= high) {
return intervals.get(low);
}
int mid = low + (high - low) / 2;
List<Interval> left = mergeHelper_v2_Divide_Conquer(intervals, low, mid);
List<Interval> right = mergeHelper_v2_Divide_Conquer(intervals, mid + 1, high);
return mergeTwoInterval(left, right);
}
private List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
// write your code here
if (list1 == null || list1.isEmpty()) {
return list2;
}
if (list2 == null || list2.isEmpty()) {
return list1;
}
List<Interval> merge = new ArrayList<>();
Interval last = null;
int i = 0, j = 0;
while (i < list1.size() && j < list2.size()) {
Interval cur;
if (list1.get(i).start <= list2.get(j).start) {
cur = list1.get(i);
i++;
} else {
cur = list2.get(j);
j++;
}
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
while (i < list1.size()) {
Interval cur = list1.get(i);
i++;
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
while (j < list2.size()) {
Interval cur = list2.get(j);
j++;
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
return merge;
}
Code3
private List<Interval> mergeHelper_v3_Non_Recursive(List<List<Interval>> intervals) {
while (intervals.size() > 1) {
List<List<Interval>> tmp = new ArrayList<>();
for (int i = 0; i < intervals.size() && i + 1 < intervals.size(); i += 2) {
List<Interval> merge = mergeTwoInterval(intervals.get(i), intervals.get(i + 1));
tmp.add(merge);
}
if (intervals.size() % 2 == 1) {
tmp.add(intervals.get(intervals.size() - 1));
}
intervals = tmp;
}
return intervals.get(0);
}
private List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
// write your code here
if (list1 == null || list1.isEmpty()) {
return list2;
}
if (list2 == null || list2.isEmpty()) {
return list1;
}
List<Interval> merge = new ArrayList<>();
Interval last = null;
int i = 0, j = 0;
while (i < list1.size() && j < list2.size()) {
Interval cur;
if (list1.get(i).start <= list2.get(j).start) {
cur = list1.get(i);
i++;
} else {
cur = list2.get(j);
j++;
}
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
while (i < list1.size()) {
Interval cur = list1.get(i);
i++;
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
while (j < list2.size()) {
Interval cur = list2.get(j);
j++;
if (last == null || last.end < cur.start) {
merge.add(cur);
last = cur;
} else {
last.end = Math.max(last.end, cur.end);
}
}
return merge;
}
Last updated