Given a collection of intervals, merge all overlapping intervals.
[分析] 这题思路不难,将输入的区间数组按左边界排序然后合并。但是调试了很久,收获是熟悉了些Java语法。首先,忘记对ArrayList排序可以使用Collections.sort(),不厌其烦地在ArrayList和数组间转换为了能使用Arrays.sort进行排序;然后使用Iterator对Arrays.asList()转化得到的ArrayList进行删除操作时遭遇了java.lang.UnsupportedOperationException, Google上查了一番并查看相应实现知道通过Arrays.asList()获取到的List并不支持add和remove等修改操作,该List对象是在Arrays中实现的一个内部类ArrayList,继承AbstractList且没有重载AbstractList的add 和remove方法。一番修改后又撞上了java.lang.IllegalArgumentException: Comparison method violates its general contract!说我的Comparator实现得不对,不满足比较的基本性质,一查发现是有个手误。不断优化得到三个版本。
[分析] 这题思路不难,将输入的区间数组按左边界排序然后合并。但是调试了很久,收获是熟悉了些Java语法。首先,忘记对ArrayList排序可以使用Collections.sort(),不厌其烦地在ArrayList和数组间转换为了能使用Arrays.sort进行排序;然后使用Iterator对Arrays.asList()转化得到的ArrayList进行删除操作时遭遇了java.lang.UnsupportedOperationException, Google上查了一番并查看相应实现知道通过Arrays.asList()获取到的List并不支持add和remove等修改操作,该List对象是在Arrays中实现的一个内部类ArrayList,继承AbstractList且没有重载AbstractList的add 和remove方法。一番修改后又撞上了java.lang.IllegalArgumentException: Comparison method violates its general contract!说我的Comparator实现得不对,不满足比较的基本性质,一查发现是有个手误。不断优化得到三个版本。
public class Solution {
Comparator<Interval> comparator = new Comparator<Interval>() {
public int compare(Interval a, Interval b) {
return a.start - b.start;
}
};
// Method 3: merge结果存储在额外List中, Method 2 的代码优化版
public List<Interval> merge(List<Interval> intervals) {
if (intervals == null || intervals.size() <= 1)
return intervals;
Collections.sort(intervals, comparator);
List<Interval> result = new ArrayList<Interval>();
int i = 0, N = intervals.size();
while (i < N) {
result.add(intervals.get(i++));
Interval last = result.get(result.size() - 1);
while (i < N && intervals.get(i).start <= last.end) {
last.end = Math.max(last.end, intervals.get(i++).end);
}
}
return result;
}
// Method 2: merge结果存储在额外List中
public List<Interval> merge2(List<Interval> intervals) {
if (intervals == null || intervals.size() <= 1)
return intervals;
Collections.sort(intervals, comparator);
List<Interval> result = new ArrayList<Interval>();
result.add(intervals.get(0));
int i = 1;
while (i < intervals.size()) {
int currEnd = result.get(result.size() - 1).end;
while (i < intervals.size() && currEnd >= intervals.get(i).end) {
i++;
}
if (i == intervals.size()) break;
if (intervals.get(i).start > currEnd)
result.add(intervals.get(i));
else
result.get(result.size() - 1).end = intervals.get(i).end;
i++;
}
return result;
}
// Method 1: 在原数组中merge
public List<Interval> merge(List<Interval> intervals) {
if (intervals == null || intervals.size() < 2)
return intervals;
Collections.sort(intervals, comparator);
int i = 0;
while (i < intervals.size() - 1) {
Interval curr = intervals.get(i);
Interval next = intervals.get(i + 1);
if (curr.end >= next.start) {
curr.end = Math.max(curr.end, next.end);
intervals.remove(i + 1);
} else {
i++;
}
}
return intervals;
}
}