Given a collection of intervals, merge all overlapping intervals.
For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].
题目大意:给定一个组区间,实现一个函数,合并这些区间。
解题思路:首先根据start排序,然后开始循环,判断当前end和下一个的start是否有overlap,没有的话,可以输出当前这个区间,有的话把后一个的end设置为max{后一个end,当前end},循环到最后,把所有符合条件的都加到res列表里。
public static List<Interval> merge(List<Interval> it) { List<Interval> res = new ArrayList<>(); if (it == null || it.size() == 0) { return res; } Comparator<Interval> comp = new Comparator<Interval>() { @Override public int compare(Interval o1, Interval o2) { if (o1.start - o2.start != 0) { return o1.start - o2.start; } return o2.end - o1.end; } }; Collections.sort(it, comp); int begin = it.get(0).start; int end = it.get(0).end; for (int i = 0; i < it.size() - 1; i++) { if (it.get(i).end < it.get(i + 1).start) { res.add(new Interval(begin, it.get(i).end)); begin = it.get(i + 1).start; } else { it.get(i + 1).end = Math.max(it.get(i).end, it.get(i + 1).end); } end = it.get(i + 1).end; } res.add(new Interval(begin, end)); return res; }
看到别人还有更高效的方案,直接遍历源List,在上面操作,不需要new新的Interval,本来想用Java8的lambada表达式写Comparator的,但是不知道为什么在提交的时候总是TLE。
public static List<Interval> merge(List<Interval> it) { List<Interval> res = new ArrayList<>(); if (it == null || it.size() == 0) { return res; } //这里如果用lambda表达式,会超时
//Comparator<Interval> comp = (o1, o2) -> o1.start - o2.start;
new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
return o1.start - o2.start;
}
};
Collections.sort(it, comp);
Interval curr;
Iterator<Interval> itor = it.iterator();
curr = itor.next();
while (itor.hasNext()) {
Interval tmp = itor.next();
if (curr.end >= tmp.start) {
curr.end = Math.max(curr.end, tmp.end);
itor.remove();
} else {
curr = tmp;
}
}
return res;
}