Leetcode 57 Insert Interval

57. Insert Interval

My Submissions
Total Accepted: 55165  Total Submissions: 234338  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].

Subscribe to see which companies asked this question

Hide Tags
  Array Sort
Hide Similar Problems
  (H) Merge Intervals


分析:

      和Leetcode 56 Merge Intervals这道题类似,这道题多了一点,需要将一个新区间插入到给定的区间集合中。

区间集合已排好序。

如果新区间与原集合重合了,那么合并。


解法1:

最容易想到的方法就是 将新区间插入到原集合 然后按照Merge Interval的方法 排序 合并。。

当然这也做是可以实现的 只不过效率并不高 因为给定的区间集合已经排好序了。。

我们需要好好利用这个条件。


下面也给出解法1的代码(已AC 2016-03-28):

vector<Interval> insert(vector<Interval>& v, Interval newv) {
	if (v.size() <= 0)
	{
		vector<Interval> res;
		res.push_back(newv);
		return res;
	}

	v.push_back(newv);
	// 先按照start从小到大排序
	sort(v.begin(), v.end(), cmp);

	vector<Interval>::iterator it = v.begin();
	int st = (*it).start, ed = (*it).end;
	vector<Interval> res;

	for (; it != v.end(); ++it)
	{
		// 除去最后一个区间
		if ((it + 1) != v.end())
		{
			// 区间不能合并
			if ((it + 1)->start > ed)
			{
				res.push_back(Interval(st, ed));
				st = (it + 1)->start;
			}
			// 要比较区间的结束 有可能出现[1 5] [2 4] 这样区间结束是较大者
			ed = ((it + 1)->end > ed) ? (it + 1)->end : ed;
		}// end if
		// 最后一个区间单独考虑
		else
		{
			if (it->start > ed)
			{
				res.push_back(Interval(st, ed));
				res.push_back(*it);
			}//end if
			else
			{
				ed = ((it)->end > ed) ? (it)->end : ed;
				res.push_back(Interval(st, ed));
			}//end else
		}//end else
	}//end for

	return res;
}

解法2:

这种解法的思路是定位新区间的位置。

只有当新区间与集合中的区间重合时,我们需要先进行合并。直至没有区间重合。

下面给出没有区间重合与区间重合的条件

假定新区间为:[newSt, newEd]

集合中区间为:[St, Ed]


无重合:

Ed < newSt  (集合区间在新区间左侧)  

St > newEd  (集合区间在新区间右侧)

重合:

Ed >= newSt or St <= newEd

【上面等号的情况也包括】

另外需要注意的是合并区间之后,合并后区间的端点值需要更新。【取较大值】


下面给出解法2的代码(已AC 2016-03-28):

vector<Interval> insert(vector<Interval>& v, Interval newv) {
	vector<Interval> res;
	if (v.size() <= 0)
	{
		res.push_back(newv);
		return res;
	}

	int i = 0, sz = v.size();

	// 找到区间插入的位置
	for (; i < sz && v[i].end < newv.start; ++i)
		res.push_back(v[i]);

	if (i == sz)
	{
		res.push_back(newv);
		return res;
	}

	newv.start = (v[i].start < newv.start) ? v[i].start : newv.start;
	// 区间重合  需要先进行合并
	for (; i < sz && v[i].start <= newv.end; ++i)
		newv.end = (v[i].end > newv.end) ? v[i].end : newv.end;

	res.push_back(newv);

	// 如果还有未重合的区间
	for (; i < sz; ++i)
		res.push_back(v[i]);

	return res;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值