【LeetCode每日一题】[困难]57. 插入区间
57. 插入区间
题目来源
算法思想:数组
题目:
思路; 依次遍历(从左往右)排好序的原区间数组,遍历的当前区间[a ,b]与待插入区间[aa, bb]有以下关系:
- 当前区间与插入区间不相交,需要直接保存当前区间:当前区间的最大值小于插入区间的最小值(b < aa);或者插入区间已经完成了插入;
- 当 aa<a, 其中分为两种情况:
- b >= aa, 此时相交, 当前区间最小值以及最大值均需要修改; 修改之后,采用向后遍实现区间的合并, 即如果两个区间相交, 区间的最大值要修改;
- b < aa,此时区间不相交,且区间没有发生插入(即第一次匹配到这里),将其直接存入list,
- 当 aa>=a, 此时相交,如果最大值发生了修改(如果没有修改,说明插入区间被当前区间包含),采用向后遍实现区间的合并, 即如果两个区间相交, 区间的最大值要修改;
java代码
class Solution {
public int[][] insert(int[][] intervals, int[] newInterval) {
int n = intervals.length + 1;//返回数组最长长度是原数组长度+1
int[][] list = new int[n][2];//返回数组
boolean flag = false;//用来标记区间是否完成插入
int i = 0;//用来遍历intervals
int j = 0;//用来遍历list
while (i < intervals.length) {
//遍历原始数组
//如果插入区间最小值大于当前区间的最大值,或者待插入区间已经插入过了,则直接将当前区间存到list中
if (newInterval[0] > intervals[i][1] || flag) {
list[j++] = intervals[i++];
continue;
}
//如果插入区间最小值小于当前区间的最小值,分为两种情况
if (newInterval[0] < intervals[i][0]) {
//1.插入区间的最大值大于等于当前区间的最小值
if (newInterval[1] >= intervals[i][0]) {
intervals[i][0] = newInterval[0];//将当前区间最小值设置成最小值(其中插入区间的最小值更小)
intervals[i][1] = Math.max(newInterval[1], intervals[i][1]);//将当前区间最大值设置最大值(需要比较谁是最大值)
//区间完成插入后,要进行区间的合并
int index = i + 1;
//向后遍历,判断是否有区间需要合并
while (index < intervals.length && intervals[i][1] >= intervals[index][0]) {
//新区间的最大值大于后面区间的最小值,需要合并
intervals[i][1] = Math.max(intervals[i][1], intervals[index][1]);//进行合并
index++;//向后继续遍历
}//直到合并完成
list[j++] = intervals[i++];//存入新区间
i = index;//i指针向后移动,因为中间的区间发生了合并
flag = true;//区间完成插入,设置成true
}else if(!flag){
//2.插入区间的最大值小于等于当前区间的最小值 且没有发生插入,则测试需要插入,
list[j++] = newInterval;//插入区间
flag = true;//区间完成插入,设置成true
}
}else if (newInterval[0] <= intervals[i][1]) {
//如果插入区间最小值大于当前区间的最小值 但小于当前区间的最大值
intervals[i][1] = Math.max(newInterval[1], intervals[i][1]);//修改区间的最大值,
//向后遍历,判断是否有区间需要合并
int index = i + 1;
while (index < intervals.length && intervals[i][1] >= intervals[index][0]) {
intervals[i][1] = Math.max(intervals[i][1], intervals[index][1]);
index++;
}
list[j++] = intervals[i++];
i = index;
flag = true;
}
}
//如果没有发生插入,则说明插入区间需要插入到末尾,进行插入
if (!flag) {
list[j++] = newInterval;
}
return Arrays.copyOf(list, j);//返回list中插入合并后的有效长度
}
}