问题:
难度:medium
说明:
输入二维数组 intervals,数组每个元素 int[] 都代表一个区间 [start, end],把重叠的合并,相互接触的不合并,输入的区间是无序的。
题目连接:https://leetcode.com/problems/merge-intervals/
输入范围:
1 <= intervals.length <= 104
intervals[i].length == 2
0 <= starti <= endi <= 104
输入案例:
Example 1:
Input: intervals = [[1,3],[2,6],[8,10],[15,18]]
Output: [[1,6],[8,10],[15,18]]
Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6].
Example 2:
Input: intervals = [[1,4],[4,5]]
Output: [[1,5]]
Explanation: Intervals [1,4] and [4,5] are considered overlapping.
我的代码:
这个比较简单,可以选择排序一遍,然后再进行比较处理,效率较差。不过不排序的话,可以用一个类似于刻度一样的 map 来暂存每一个区间的占有位置,然后进行处理。
class Solution {
public int[][] merge(int[][] intervals) {
int[] map = new int[10001];
int len = intervals.length, index = 0, max = 0;
for(int i = 0;i < len;i ++) {
boolean flag = true;
int[] arr = intervals[i];
max = Math.max(max, arr[1]); // 做区间限制,不过多遍历
if(map[arr[0]] == 0)
map[arr[0]] = 2;
else
flag = false;
for(int j = arr[0] + 1;j <= arr[1];j ++) {
flag = map[j] == 0;
map[j] = 1;
}
}
for(int i = 0;i <= max;) {
if(map[i] == 2) {
intervals[index][0] = i;
while(i <= max && map[++ i] == 1); // 遍历区间
intervals[index ++][1] = i - 1;
} else i ++;
}
// 结果集
int[][] res = new int[index][2];
for(int i = 0;i < index; i ++) {
res[i] = intervals[i];
}
return res;
}
}
如果用排序的话,代码比较清晰
class Solution {
public int[][] merge(int[][] intervals) {
int len = intervals.length, len2 = 1, index = 0;
Arrays.sort(intervals, new Comparator<int[]>() { // arr[0]升序
@Override
public int compare(int[] o1, int[] o2) {
if (o1[0] == o2[0]) return o1[1] - o2[1];
return o1[0] - o2[0];
}
});
for(int i = 1;i < len;i ++) {
int[] arr = intervals[i];
int[] pre = intervals[i - 1];
if(arr[0] <= pre[1]) {
arr[0] = pre[0];
arr[1] = Math.max(arr[1], pre[1]); // 这里得要比较
pre[0] = pre[1] = -1;
} else len2 ++;
}
// 结果集
int[][] res = new int[len2][2];
for(int i = 0;i < len; i ++)
if(intervals[i][0] != -1) res[index ++] = intervals[i];
return res;
}
}