题目描述
分析
该题并不像其标签‘difficult’一样的难,其实就是一个对集合(区间)取并集的操作。
插入了一个新区间来取并集,关键就在于判断出原区间集中受新区间的覆盖影响情况以及确切的起始结束位置,剩下的区间照搬即可。代码
编程的思路请留意注释的内容。
/**
* Definition for an interval.
* struct Interval {
* int start;
* int end;
* };
*/
/**
* Return an array of size *returnSize.
* Note: The returned array must be malloced, assume caller calls free().
*/
struct Interval* insert(struct Interval* intervals, int intervalsSize, struct Interval newInterval, int* returnSize) {
struct Interval* result;
result = (struct Interval * )malloc((intervalsSize+1) * sizeof(struct Interval));
bool isinsert=false;
int holdmin,holdmax;
int Size=0;
for(int i=0;i<intervalsSize;){
//照搬在新区间左边的区间集合(与新区间无交集)
if(newInterval.start>intervals[i].end){
result[Size++]=intervals[i];
i++;
}
else{
//新区间与原区间集无交集
if(newInterval.end<intervals[i].start){
result[Size++]=newInterval;
isinsert=true;
}
else{
//确定受新区间影响部分的起始位置
holdmin=newInterval.start>intervals[i].start?intervals[i].start:newInterval.start;
holdmax=newInterval.end>intervals[i].end?newInterval.end:intervals[i].end;
newInterval.start=holdmin;
newInterval.end=holdmax;
i++;
//确定受新区间影响部分的终止位置
while(i<intervalsSize){
if(newInterval.end<intervals[i].start){
result[Size++]=newInterval;
isinsert=true;
break;
}
else{
newInterval.end=newInterval.end>intervals[i].end?newInterval.end:intervals[i].end;
}
i++;
}
}
//照搬在新区间右边的区间集合(与新区间无交集)
while(i<intervalsSize){
result[Size++]=intervals[i++];
}
}
}
//新区间被插在了最末尾
if(!isinsert){
result[Size++]=newInterval;
}
*returnSize=Size;
return result;
}
- 后记
上述实现的时间复杂度为O(n)。
该题型让我很容易联想到另一种题型:给出一系列区间求并集的题型。其实现的思想和插入一个区间求并集差不多。