2021年11月24日
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
思路分析:此题的思路是先对原二维数组内部的数据进行排序(排序的依据为每一个区间的左端点),这样整体就会变成如下图所示的样子,在将数组中的第一个区间加入到结果集当中之后。
如果下一个区间的左端点小于已经加入到结果集内最后一个区间的右端点,则需要比较结果集中最后一个区间的右端点与想要添加进结果集的区间的右端点的大小,如果后者大,则更新结果集最后一个区间的右端点,前者大,则无需更新,判断下一个区间即可。
如果下一个区间的左端点大于已经加入到结果集内的最后一个区间的右端点,则直接将其添加进结果集做随后的判断,原二维数组遍历结束则结束。
(假设上边的区间是已经添加进结果集的最后一个区间)
情况一:下一个区间的左端点小于已经加入到结果集内最后一个区间的右端点,且后者的右端点大于前者的右端点,则更新结果集最后一个区间的右端点。
情况二:下一个区间的左端点小于已经加入到结果集内最后一个区间的右端点,且后者的右端点小于前者的右端点,则不动。
情况三:下一个区间的左端点大于已经加入到结果集内最后一个区间的右端点,则直接将下一个区间添加进结果集。
代码和提交结果如下图:
class Solution {
public int[][] merge(int[][] intervals) {
if(intervals.length == 0){
return new int[0][2];
}
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
List<int[]> result = new ArrayList<>();
for (int i = 0; i < intervals.length; i++) {
int l = intervals[i][0];
int r = intervals[i][1];
if(result.size() == 0 || l > result.get(result.size()-1)[1]){
result.add(new int[]{l,r});
}else {
result.get(result.size()-1)[1] = Math.max(result.get(result.size()-1)[1],r);
}
}
return result.toArray(new int[result.size()][]);
}
}
题目总结:在这道题当中,除了做题思路之外还有两个点。
一、排序的方法,刚开始我是用的手写的冒泡来进行的排序,时间复杂度O(n2),虽然可以提交通过,但是执行用时达到了160ms之高。但是最后发现使用快排效率会得到很大的提高,用到了如下的代码:
Arrays.sort(intervals, new Comparator<int[]>() {
@Override
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
其中实现了Comparator接口来进行定制排序。这是第一个点。
二、最后将List<int []>转二维数组返回
因为题目要求的是返回二维数组,所以最后要使用List的toArray方法,代码如下图:
return result.toArray(new int[result.size()][]);
如有错误,还请提出。