我的LeetCode代码仓:https://github.com/617076674/LeetCode
原题链接:https://leetcode-cn.com/problems/insert-interval/description/
题目描述:
知识点:排序、数组
思路:寻找合并区间的起点和终点
以示例2举例说明,其合并区间的起点是1,因为newInterval的起点是4,其介于intervals数组的索引为1的元素的起点和终点之间。其合并区间的终点是3,因为newInterval的终点是8,其介于intervals数组的索引为3的元素的起点和终点之间。
假如我们把newInterval改为[4, 11],那么对于其终点11,在intervals数组中我们找不到任意一个包含11的区间。这时,我们将终点定为3。因为对于11而言,其介于10和12之间,10是intervals数组中索引为3的元素的终点,而12是intervals数组中索引为4的元素的起点。对于newInterval的起点,如果在intervals数组中我们找不到任意一个包含newInterval的起点的区间,我们也采用相同的做法。
需要注意的是:start和end的起始值应该被赋值为-1。
加入start和end的起始值被赋值为0,那么对于intervals = [[1, 3]], newInterval = [0, 0]的情况,其start值和end值均为0。而对于newInterval = [1, 2]的情况,其start值和end值也均为0。而显然,对于newInterval = [0, 0]的情况,我们是不能合并的,而对于newInterval = [1, 2]的情况,我们需要将结果合并为[[1, 3]]。
我们用start和end为-1,来代表在intervals数组的开始位置插入新区间newInterval。
在计算start和end的过程中,时刻要注意数组的索引越界问题。
对于合并后的新数组insertInterval,其起点和终点的计算也比较复杂,需要分多种情况进行讨论。
(1)如果start == intervals.size(),说明新插入的索引应该在intervals数组的最后,且无需合并。因此insertInterval的起点和终点均与newInterval相同。
(2)如果end == -1,说明新插入的索引应该在intervals数组的最前面,也无需合并。因此insertInterval的起点和终点均与newInterval相同。
(3)除了(1)(2)中的情形外,
a.如果start == -1,说明insertInterval的起点和newInterval的起点相同。否则,insertInterval的起点应该取intervals数组中索引为start的区间的起点和newInterval的起点之中的较小值。
b.如果end == intervals.size(),说明insertInterval的终点和newInterval的终点相同。否则,insertInterval的终点应该取intervals数组中索引为end的区间的终点和newInterval的终点之中的较大值。
最后,我们把原来的intervals集合中索引在[start, end]中的元素用insertInterval这一个元素代替,生成新的list集合即可。
时间复杂度是O(n)级别的,其中n为intervals集合的大小。空间复杂度是O(1)。
JAVA代码:
public class Solution {
public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
List<Interval> list = new ArrayList<>();
int start = -1;
int end = -1;
for (int i = 0; i < intervals.size(); i++) {
if(newInterval.start >= intervals.get(i).start && newInterval.start <= intervals.get(i).end) {
start = i;
}
if(newInterval.start > intervals.get(i).end) {
if(i + 1 == intervals.size()) {
start = intervals.size();
}else if(newInterval.start < intervals.get(i + 1).start) {
start = i + 1;
}
}
if(newInterval.end >= intervals.get(i).start && newInterval.end <= intervals.get(i).end) {
end = i;
}
if(newInterval.end > intervals.get(i).end) {
if(i + 1 == intervals.size()) {
end = intervals.size();
}else if(newInterval.end < intervals.get(i + 1).start) {
end = i;
}
}
}
Interval insertInterval = new Interval();
if(start == intervals.size() || end == -1) {
insertInterval.start = newInterval.start;
insertInterval.end = newInterval.end;
}else {
if(start == -1) {
insertInterval.start = newInterval.start;
}else {
insertInterval.start = Math.min(newInterval.start, intervals.get(start).start);
}
if(end == intervals.size()) {
insertInterval.end = newInterval.end;
}else {
insertInterval.end = Math.max(newInterval.end, intervals.get(end).end);
}
}
for (int i = 0; i < start; i++) {
list.add(intervals.get(i));
}
list.add(insertInterval);
for (int i = end + 1; i < intervals.size(); i++) {
list.add(intervals.get(i));
}
return list;
}
}
LeetCode解题报告: