开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的27天,点击查看活动详情
题目:LeetCode
以数组 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] 可被视为重叠区间。
提示:
intervals[i].length == 2
解题思路
分析题意可以用排序加二分查找。以区间开始值作为主键来排序和查找。
用一个集合来保存结果,这个集合里面的所有的区间都是不重叠的。
新来一个区间时inter,在结果集合中找到它的left,也就是left[0]<=inter[0], 以及找到right,也就是right[0]>=inter[0]。
有几种情况,当inter与left和right都不重叠时,就要把inter直接加入到集合中。
仅与left有重叠时,就与left合并,把left移除,加入合并后的区间。
仅与right有重叠时,移除right,加入合并后的区间。
如果与left和right都有重叠时,把left, right都移除,然后加入合并后的区间。
这里的集合,用TreeMap比较合适。TreeMap能做到查删加都是log(n)的,所以整体时间复杂度是在O(nlogn)。
如果用数组代替TreeMap,二分查找能做到log(n),但添加和删除只能到O(n),整体会逊于TreeMap。
代码实现
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
TreeMap < Integer, Integer > map = new TreeMap < > ();
for (int[] in : intervals) {
Map.Entry < Integer, Integer > floor = map.floorEntry( in [0]);
Map.Entry < Integer, Integer > ceil = map.ceilingEntry( in [0]);
// not intersect with floor
boolean offFloor = floor == null || floor.getValue() < in [0];
// not intersect with ceil
boolean offCeil = ceil == null || ceil.getKey() > in [1];
if (offFloor && offCeil) {
map.put( in [0], in [1]);
} else if (!offFloor && !offCeil) {
// merge with floor and ceil
map.remove(floor.getKey());
map.remove(ceil.getKey());
map.put(floor.getKey(), Math.max(ceil.getValue(), in [1]));
} else if (!offFloor) {
// merge with floor
map.remove(floor.getKey());
map.put(floor.getKey(), Math.max( in [1], floor.getValue()));
} else if (!offCeil) {
// merge with ceil
map.remove(ceil.getKey());
map.put( in [0], Math.max( in [1], ceil.getValue()));
}
}
int[][] result = new int[map.size()][2];
int index = 0;
for (Map.Entry < Integer, Integer > entry: map.entrySet()) {
result[index] = new int[] {
entry.getKey(), entry.getValue()
};
index++;
}
return result;
}
运行结果
复杂度分析
- 空间复杂度:
- 时间复杂度:
在掘金(JUEJIN) 一起分享知识, Keep Learning!