基础算法——区间和并

1. 区间和并
把有交集的区间合成一个大的区间
2. 算发步骤
1)把要合并的区间按区间左端点从小到大排序
2)用st和ed指针从前往后维护区间
3)比较ed 和后一个区间的左端点,分情况更新ed和first
3. 模板

// 将所有存在交集的区间合并
void merge(vector<PII> &segs)
{
    vector<PII> res;

    sort(segs.begin(), segs.end());

    int st = -2e9, ed = -2e9;
    for (auto seg : segs)
        if (ed < seg.first)
        {
            if (st != -2e9) res.push_back({st, ed});
            st = seg.first, ed = seg.second;
        }
        else ed = max(ed, seg.second);

    if (st != -2e9) res.push_back({st, ed});

    segs = res;
}

4. 例题
给定 n个区间 [li, ri],要求合并所有有交集的区间。
注意如果在端点处相交,也算有交集。
输出合并完成后的区间个数。
例如:[1,3]和[2,6]可以合并为一个区间[1,6]。
输入格式
第一行包含整数n。
接下来n行,每行包含两个整数 l 和 r。
输出格式
共一行,包含一个整数,表示合并区间完成后的区间个数。
数据范围
1≤n≤100000,−109≤li≤ri≤109
输入样例:
5
1 2
2 4
5 6
7 8
7 9
输出样例:
3

#include
#include
#include

using namespace std;

const int N = 100010;
typedef pair<int, int> PII;

int n;
vector<PII> segs;	//储存所有区间

void merge(vector<PII> & segs)
{
	vector<PII> res;

	sort(segs.begin(), segs.end());
	
	int st = -2e9, ed = -2e9;
	for(auto seg : segs)
	{
		if(ed < seg.first)
		{
			if(st != -2e9) res.push_back({st, ed});
			st = seg.first, ed = seg.second;
		}
		else ed = max(ed, seg.second);
	}

	if(st != -2e9) res.push_back({st, ed});
	
	segs = res;	
}	
			
int main()
{	
	cin >> n;
	for(int i = 0; i < n; i++)
	{
		int l, r;
		cin >> l >> r;
		segs.push_back({l, r});
	}

	merge(segs);

	cout << segs.size() << endl;
	return 0;
}		

[^1]注:此文章中的代码和模板均来自www.acwing.com

你可能感兴趣的:(基础算法——区间和并)