57. 插入区间
题目描述
给出一个无重叠的 ,按照区间起始端点排序的区间列表。
在列表中插入一个新的区间,你需要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间)。
示例1:
输入:intervals = [[1,3],[6,9]], newInterval = [2,5]
输出:[[1,5],[6,9]]
示例2:
输入:intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
输出:[[1,2],[3,10],[12,16]]
解释:这是因为新的区间 [4,8] 与 [3,5],[6,7],[8,10] 重叠。
题解:
题目已经保证区间没有重叠,且左端点从小到大排序,那么就非常容易了,设新插入的区间左右端点为 s
和 e
,从左往右遍历每个区间:
- 若
seg[i][0] > e
,说明没有交集,且此时找到了新插入区间的位置,将{s, e}
保存到结果中,同时将seg[i]
保存到结果中 - 若
seg[i][1] < s
,说明没有交集,将seg[i]
保存到结果中 - 否则的话,说明有交集,因为
i
后面的区间也可能会继续与{s, e}
产生交集,所以更新s = min( s, seg[i][0] ), e = max( e, seg[i][1])
- 如果遍历完所有区间,都没有找到
{s, e}
的插入位置,则把{s, e}
插入到结果末尾
时间复杂度: O ( n ) O(n) O(n)
额外空间复杂度: O ( n ) O(n) O(n)
写法一:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
int n = intervals.size();
if ( !n || newInterval[1] < intervals[0][0] ) {
intervals.insert( intervals.begin(), move(newInterval) );
return intervals;
}
if ( newInterval[0] > intervals.back()[1] ) {
intervals.push_back( move(newInterval) );
return intervals;
}
vector<vector<int>> ret;
int s = newInterval[0], e = newInterval[1];
bool flag = false;
for ( int i = 0; i < n; ++i ) {
if ( intervals[i][1] < s ) {
ret.push_back( move(intervals[i]) );
} else if ( intervals[i][0] > e ) {
if ( !flag ) {
ret.push_back( {s, e} );
flag = true;
}
ret.push_back( move(intervals[i]) );
} else {
s = min( s, intervals[i][0] );
e = max( e, intervals[i][1] );
}
}
if ( !flag ) ret.push_back({s, e});
return ret;
}
};
/*
时间:16ms,击败:99.36%
内存:16.6MB,击败:99.15%
*/
写法二:
class Solution {
public:
vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
int n = intervals.size();
if ( !n || newInterval[1] < intervals[0][0] ) {
intervals.insert( intervals.begin(), move(newInterval) );
return intervals;
}
if ( newInterval[0] > intervals.back()[1] ) {
intervals.push_back( move(newInterval) );
return intervals;
}
vector<vector<int>> ret;
int s = newInterval[0], e = newInterval[1];
int k = 0;
while ( k < n && intervals[k][1] < s ) ret.push_back( move(intervals[k++]) );
if ( k < n ) {
s = min( s, intervals[k][0] );
while ( k < n && intervals[k][0] <= e ) e = max( e, intervals[k++][1] );
}
ret.push_back({s, e});
while ( k < n ) ret.push_back( move(intervals[k++]) );
return ret;
}
};
/*
时间:12ms,击败:99.84%
内存:16.5MB,击败:99.44%
*/