LeetCode57插入区间
题目描述
给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
典型的贪心问题,需要对二维数组起始端点进行排序。
注意以下用法:
LinkedList<int[]> output = new LinkedList<int[]>(); 可以存储二维数组
return output.toArray(new int[output.size()][2]); 可以输出二维数组
二维数组排序
Arrays.sort(intervals, new Comparator<int[]>() {
public int compare(int[] interval1, int[] interval2) {
return interval1[0] - interval2[0];
}
});
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
// init data
int newStart = newInterval[0], newEnd = newInterval[1];
int idx = 0, n = intervals.length;
LinkedList<int[]> output = new LinkedList<int[]>();
// add all intervals starting before newInterval
while (idx < n && newStart > intervals[idx][0])
output.add(intervals[idx++]);
// add newInterval
int[] interval = new int[2];
// if there is no overlap, just add the interval
if (output.isEmpty() || output.getLast()[1] < newStart)
output.add(newInterval);
// if there is an overlap, merge with the last interval
else {
interval = output.removeLast();
interval[1] = Math.max(interval[1], newEnd);
output.add(interval);
}
// add next intervals, merge with newInterval if needed
while (idx < n) {
interval = intervals[idx++];
int start = interval[0], end = interval[1];
// if there is no overlap, just add an interval
if (output.getLast()[1] < start) output.add(interval);
// if there is an overlap, merge with the last interval
else {
interval = output.removeLast();
interval[1] = Math.max(interval[1], end);
output.add(interval);
}
}
return output.toArray(new int[output.size()][2]);
}
}
对于区间s1[l1,r1],s2[l2,r2],如果两个区间没有交集,那么s1在s2左侧,或者s2在s1左侧,那么有l2>r1或者l1>r2,
否则有交集。其并集为[min(l1,l2),max(r1,r2)]
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int left = newInterval[0];
int right = newInterval[1];
boolean placed = false;
List<int[]> ansList = new ArrayList<int[]>();
for (int[] interval : intervals) {
if (interval[0] > right) {
// 在插入区间的右侧且无交集
if (!placed) {
ansList.add(new int[]{left, right});
placed = true;
}
ansList.add(interval);
} else if (interval[1] < left) {
// 在插入区间的左侧且无交集
ansList.add(interval);
} else {
// 与插入区间有交集,计算它们的并集
left = Math.min(left, interval[0]);
right = Math.max(right, interval[1]);
}
}
if (!placed) {
ansList.add(new int[]{left, right});
}
//注意二维数组和ArrayList的转化
int[][] ans = new int[ansList.size()][2];
for (int i = 0; i < ansList.size(); ++i) {
ans[i] = ansList.get(i);
}
return ans;
}
}