56.合并区间
题目描述:
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。
请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
思路与解法(一)——排序
对各区间的左边界进行升序排列,那么在排完序后的区间集合中,可合并的区间一定是连续的。
若左边区间的右边界小于右边区间的左边界,则不做合并。若左边区间的右边界小于等于右边区间的左边界,则做合并。
Java实现如下
class Solution{
public int[][] merge(int[][] intervals){
// 若为空则返回
if (intervals.length == 0){
return new int[0][2];
}
// 对各区间左边界进行升序排列
Arrays.sort(intervals, new Comparator<int[]>(){
// 重写Comparator的compare方法,为负表示小于,为正表示大于
public int compare(int[] interval1, int[] interval2){
return interval1[0] - interval2[0];
}
});
// 创建merged集合记录合并后的
List<int[]> merged = new ArrayList<>();
for(int i = 0; i < intervals.length; i++){
// 记录左右边界
int l = intervals[i][0], r = intervals[i][1];
// 若集合为空或左边区间的右边界小于右边区间的左边界,则直接加上
if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < l){
merged.add(new int[]{l,r});
} else{
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], r);
}
}
return merged.toArray(new int[merged.size()][]);
}
}
关于用new Comparator<int[ ]>比较进行各区间排序的原理,在查阅多篇博客和阅读源码后,我的总结是:
根据API可知,Arrays.sort 还有种重载形式:sort(T[ ] a, Comparator<? super T> c) ,这个方法参数的写法用到了泛型。可以把它理解成这样的形式: sort(Object[ ] a, Comparator c) ,这个方法的意思是按照比较器 c 给出的比较排序的依据,对 Object 数组进行排序。Comparator 接口中定义了两个方法: compare(Object o1, Object o2) 和 equals 方法,由于 equals 方法所有对象都有的方法,因此当我们实现 Comparator 接口时,我们只需重写 compare 方法,而不需重写 equals 方法。 Comparator 接口中对重写 equals 方法的描述是:“注意,不重写 Object.equals(Object) 方法总是安全的。然而,在某些情况下,重写此方法可以允许程序确定两个不同的 Comparator 是否强行实施了相同的排序,从而提高性能。”。我们只需知道第一句话就OK了,也就是说,可以不用去想应该怎么实现 equals 方法,因为即使我们不显式实现 equals 方法,而是使用Object类的 equals 方法,代码依然是安全的。
(修改自 剑指Offer——巧妙使用sort(List<T>,Comparator<? super T>)比较器)
关于 “比较器Comparator给出了比较排序的依据” 的理解
* @return a negative integer, zero, or a positive integer as the
* first argument is less than, equal to, or greater than the
* second.
*/
int compare(T o1, T o2);
这是Comparator接口的compare方法源码的部分注释,意思是,
返回值若是一个负数,表示o1 < o2;若是正数,表示o1 > o2;为0则表示相等。
Arrays.sort()源码
public static void sort(int[] a) {
DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);
}
调用DualPivotQuicksort的sort方法,作用就是实现一个快速排序(这也是复杂度分析的依据)。
复杂度分析
时间复杂度:主要开销在排序上,因为是快速排序所以为O(nlogn)。
空间复杂度:排序所需要的空间复杂度(?)O(logn)。
——56.合并区间&spm=1001.2101.3001.5002&articleId=114230430&d=1&t=3&u=f1ba79c870a8490bb2586d7d5b2a9635)
1713

被折叠的 条评论
为什么被折叠?



