[leetcode]Insert Interval

本文介绍了一种在已排序的非重叠区间中插入新区间并进行必要合并的算法实现。通过查找插入位置并处理边界条件,确保了新区间的正确插入及与原区间可能的重合部分的合并。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Insert Interval

Difficulty:hard

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:
Given intervals [1,3],[6,9], insert and merge [2,5] in as [1,5],[6,9].

Example 2:
Given [1,2],[3,5],[6,7],[8,10],[12,16], insert and merge [4,9] in as [1,2],[3,10],[12,16].

This is because the new interval [4,9] overlaps with [3,5],[6,7],[8,10].

题目大概就是在一个一个的时间段中,插入一个时间段,与原来的时间段重合的地方要进行合并。

我的做法是先找出要插入时间段的起点和终点所应该插入的位置,然后再对起点到终点之间的原有时间段进行相应的处理,有很多边界条件需要注意。

vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {

	int insertStart = -1; //起点插入位置
	int insertEnd = -1; //终点插入位置

	bool isMiddleStart = true; //起点插入位置是否位于某个原有时间段的中间
	bool isMiddleEnd = true;//终点插入位置是否位于某个原有时间段的中间

	vector<Interval>::iterator it = intervals.begin();
	vector<Interval>::iterator it_start;
	vector<Interval>::iterator it_end;

	int k = 0;
	while (k < intervals.size() && insertStart < 0 ){//找插入头的位置 找到首个大于起点的时间段
	    if (intervals[k].start >= newInterval.start || intervals[k].end >= newInterval.start){
		    insertStart = k;
		    it_start = it;
			if (intervals[k].start > newInterval.start){//判断是否在中间
				isMiddleStart = false;
			}
			break;
		}

		k++;
		it++;
	}

	while (k < intervals.size() &&  insertEnd < 0){//插入尾的位置 找到首个大于终点的时间段

		if (intervals[k].start >= newInterval.end || intervals[k].end >= newInterval.end){
			insertEnd = k;
			it_end = it;
			if (intervals[k].start > newInterval.end){//判断是否在中间
				isMiddleEnd = false;
			}
			break;
		}
		k++;
		it++;
	}


	if (insertStart == insertEnd){ //起点终点在同一个位置
		if (insertStart < 0 && insertEnd < 0){//在末尾
			intervals.push_back(newInterval);
			return intervals;
		}
		else{//开头或中间
			if (!isMiddleStart && !isMiddleEnd){ //起点和终点都不在原有时间段中间
				intervals.insert(it_start, newInterval);
				return intervals;
			}
			else if (!isMiddleStart && isMiddleEnd){//终点在原有时间段中间
				it_start->start = newInterval.start;
				return intervals;
			}
			else{//起点和终点都在原有时间段中间
				return intervals;
			}
		}
	}

	//起点终点不在同一个位置
	if (insertEnd > 0){//终点不在数组在最后的情况
		if (!isMiddleStart && !isMiddleEnd){
			intervals.erase(it_start, it_end);
			intervals.insert(it_start, newInterval);
		}
		else if (!isMiddleStart && isMiddleEnd){
			intervals.erase(it_start, it_end);
			it_start->start = newInterval.start;
		}
		else if (isMiddleStart && !isMiddleEnd){
			vector<Interval>::iterator it_tmp = it_start + 1;
			intervals.erase(it_tmp, it_end);
			it_start->end = newInterval.end;
		}
		else{
			it_end->start = it_start->start;
			intervals.erase(it_start, it_end);
		}
	}
	else{//终点在数组在最后的情况
		if (isMiddleStart){
			vector<Interval>::iterator it_tmp = it_start + 1;
			intervals.erase(it_tmp, intervals.end());
			it_start->end = newInterval.end;
		}
		else{
			intervals.erase(it_start, intervals.end());
			intervals.push_back(newInterval);
		}
	}


	return intervals;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值