【LeetCode】算法详解#4 ---合并区间
1.题目介绍
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回 一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间 。
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104
2.解决思路
题目的意思是给我们一个由许多个长度为2的小数组组成的大数组,将其中每个小数组看成一个整数区间,我们需要将其中存在重合的区间代表的数组进行合并,即[1,3][2,6]代表的两个区间存在重复范围,所以他们重合的结果就是[1,6]。所以要完成这个需求,我们首先想到的就是遍历这个数组,取出他们的区间的左右值进行比较,如果比较存在重合就进行合并并存入结果。考虑到小数组的左区间可能不是递增的,所以我们需要先对其进行排序,排序后能够保证在整个大数组中区间的左值一定小于区间的右值。
3.步骤讲解
1.当数组为空时,我们直接返回一个空数组即可
2.对大数组进行排序,以其中小数组区间的左值的大小进行升序排序
3.定义结果集合,用于存储合并后的结果数组
4.遍历数组,定义L和R记录每次遍历到的小数组区间的左值和右值
5.对结果集合进行判断,如果结果集合为空或者其中最后一个数组的右边界小于当前遍历到的数组的左边界时;要么首次遍历到,需要首先对结果结合进行初始化,要么说明本次遍历到的区间与上一个区间不重合。这两种情况都需要直接将本次的数组直接插入集合。
如果不是上面两种情况,则说明当前遍历到的数组区间与结果集合中的数组区间存在重合,需要进行合并。但我们是前面的排序是对区间的左值进行的排序,所以可能存在一些左值相同的数组,其右值是乱序的([0,3][0,1][0,2]),所以我们在合并时不能简单的直接将新的右值赋值到区间当前的右值,需要进行比较取其较大值。
6.最终结果数组集合中存储着所有合并后的数组,对集合转为数组后进行返回
4.代码展示
public static int[][] test(int[][] intervals){
//排除空数组情况
if (intervals.length == 0) {
return new int[0][2];
}
//以子数组中首个元素大小数组进行升序排序
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
//定义数组结果集合
List<int[]> merged = new ArrayList<int[]>();
//遍历数组
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()][2]);
}
5.执行结果
在leetcode中测试用例平均耗时7ms
内存分布45.72MB