1. 程式人生 > >56. 合併區間(C++)

56. 合併區間(C++)

給出一個區間的集合,請合併所有重疊的區間。

示例 1:

輸入: [[1,3],[2,6],[8,10],[15,18]]
輸出: [[1,6],[8,10],[15,18]]
解釋: 區間 [1,3] 和 [2,6] 重疊, 將它們合併為 [1,6].

示例 2:

輸入: [[1,4],[4,5]]
輸出: [[1,5]]
解釋: 區間 [1,4] 和 [4,5] 可被視為重疊區間。

【思路】

第一步:先按照座標軸,將區間排列。具體演算法實現就是以區間裡元素start升序排列。

第二步:將重合的區域組合成新的區域

組合新的區間的具體演算法為:

1.定義一個Interval temp 存放新組合的區間start和end;

2.迴圈判斷前一個區間的end和後一個區間的start的大小,若end>start則說明有交集,再判斷後一個區間的的end和前一個區間的end,若後面的end比前一個區間end小,則前面區間包含後面的區間。誰大就將誰賦值給temp的end。

3.當沒有交集的時候跳出內部迴圈,將新的區間填充到結果集,再進入下一個區域(可能有交集,也可能沒有交集)。

class Solution {
public:
     static bool cmp(Interval a, Interval b)
     {
         return a.start < b.start;
     }
  vector<Interval> merge(vector<Interval>& intervals) {
	if (intervals.size() <= 1) return intervals;//集合為空或者為一個區間
	vector<Interval> res;
	sort(intervals.begin(), intervals.end(), cmp);//排序,規定使用這種按start升序排列
	int i = 0;
	Interval temp = { intervals[0].start, intervals[0].end };//賦初值,temp為組合新的區間
	while (i < intervals.size())
	{
		temp.start = intervals[i].start;
		temp.end = intervals[i].end;
		while (i < intervals.size())
		{
			if (i < intervals.size()-1 && temp.end >= intervals[i + 1].start)//防止陣列訪問越界i < intervals.size()-1;前後區間有交集
			{
				if (temp.end < intervals[i + 1].end)//後面的區間沒有包含進來
				{
					temp.end = intervals[i + 1].end;//將後面區間合併成更大的區間
				}

				i++;
			}
			else//前後區間沒有交集
			{
				i++;
				break;
			}

		}
		res.push_back(temp);
	}

	return res;

}
};