[Java恶补day14] 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] 可被视为重叠区间。
提示:
1 <= intervals.length <= 10 4 10^4 104
intervals[i].length == 2
0 <= starti <= endi <= 10 4 10^4 104
知识点:
数组、排序
解:
因为需要合并若干个区间,因此对左端点进行升序排序,使用到lambda表达式。
对于每个区间,左端点表示这个区间的起始下标,右端点表示这个区间的结束下标。
定义一个列表,存储结果,列表的每个元素都是一个int类型的一维数组。
对于intervals的每个元素(即:每一行),按照以下步骤进行:
①获取当前结果列表res
的大小
②若当前结果列表res
没有元素,表示我们直接原始数组的第一行加入这个结果列表res
③若当前结果列表res
有元素,且最后一个元素的右端点≥当前遍历的元素的左端点,如:[1, 3]与[2, 5],表明需要合并区间。因为这个区间已经在结果列表res
中,我们做的就是替换这个区间在res
的相应左端点:获取更大的结束下标。对于这个例子而言,最大的结束下标是5,也就是p[1],因此让结果列表res
中的最后一个元素的右端点更新为这个5。若[1, 4]与[2, 3],则最大的结束下标是4,也就是res.get(len-1)[1],因此结果列表res
中的最后一个元素的右端点更新为这个4。
④若当前结果列表res
有元素,但最后一个元素的右端点<当前遍历的元素的左端点,则表明无法与当前正在处理的结果列表中的最后一个区间进行合并,那就往res
新增一个元素。
最后,我们将List列表,通过.toArray()
转为数组,返回。
时间复杂度: O ( n l o g n ) O(nlog n) O(nlogn)。Arrays.sort()
平均耗时 O ( n l o g n ) O(nlog n) O(nlogn)
空间复杂度: O ( 1 ) O(1) O(1)。排序的栈开销和返回值不计入
class Solution {public int[][] merge(int[][] intervals) {List<int[]> res = new ArrayList<>(); //最后一个元素表示正在合并的区间//原始数据按第一列进行排序Arrays.sort(intervals, (o1, o2) -> (o1[0] - o2[0]));//遍历每一行for (int[] p : intervals) {//获取当前结果列表的大小int len = res.size();//若结果列表有元素,且可合并if (len > 0 && res.get(len - 1)[1] >= p[0]) {//更新右端点最大值res.get(len - 1)[1] = Math.max(res.get(len - 1)[1], p[1]);}//无法合并else {//添加新的合并区间res.add(p);}}//列表转数组并返回return res.toArray(new int[res.size()][]);}
}
参考:
1、灵神解析
2、java二维数组排序