题目地址:
https://www.lintcode.com/problem/merge-two-sorted-interval-lists/description
给定两个list,每个list的元素都是区间,同一个list里的区间不互相有重合,并且都按照递增顺序排好序,但不同的list里的区间可能有重合。要求返回一个list,这个list里的区间是上面两个list中的区间充分合并后产生的区间。
主要思路是这样的,先开一个list名为res,存储最后要返回的结果;接着,先用两个指针分别指向两个list的头部,然后比较两个区间的左端点,挑出左端点较小的,将其与res中最后一个区间进行比较,如果可以合并则合并,否则就将那个区间之间append到res后面。如此这样,直到所有区间都合并或者append到res后面为止,代码如下:
import java.util.ArrayList;
import java.util.List;
public class Solution {
/**
* @param list1: one of the given list
* @param list2: another list
* @return: the new sorted list of interval
*/
public List<Interval> mergeTwoInterval(List<Interval> list1, List<Interval> list2) {
// write your code here
if (list1 == null) {
return list2;
} else if (list2 == null) {
return list1;
}
int i = 0, j = 0;
// cur代表list1和list2中将要加入res的区间
Interval cur = null;
List<Interval> res = new ArrayList<>();
while (i < list1.size() && j < list2.size()) {
Interval i1 = list1.get(i), i2 = list2.get(j);
// 如果i1左端点较小,说明i1将被加入res中,
// 所以令cur = i1,同时将i加一以便后面继续加入
// 如果i2左端点较小,也类似操作
if (i1.start <= i2.start) {
cur = i1;
i++;
} else {
cur = i2;
j++;
}
// 如果res为空,那就直接将区间加进去
// 否则将res末尾的区间与cur进行合并
if (res.isEmpty()) {
res.add(cur);
} else {
merge(res, res.get(res.size() - 1), cur);
}
}
// 如果list1已经全被加进去了,则将list2的区间一个一个merge进res中
while (j < list2.size()) {
merge(res, res.get(res.size() - 1), list2.get(j++));
}
// 与上同
while (i < list1.size()) {
merge(res, res.get(res.size() - 1), list1.get(i++));
}
return res;
}
// 功能是将res末尾的区间与cur合并后加入res
private void merge(List<Interval> res, Interval last, Interval cur) {
// 如果last与cur不相交,那直接将cur加进res即可
// 否则直接拓展last的右端点
if (last.end < cur.start) {
res.add(cur);
} else {
last.end = Math.max(last.end, cur.end);
}
}
}
class Interval {
int start, end;
Interval(int start, int end) {
this.start = start;
this.end = end;
}
}
时间复杂度 O ( m + n ) O(m+n) O(m+n),空间 O ( 1 ) O(1) O(1)。