LeetCode a Day(四)——56.合并区间

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)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值