力扣2406. 将区间分为最少组数(贪心)
给你一个二维整数数组 intervals ,其中 intervals[i] = [lefti, righti] 表示 闭 区间 [lefti, righti] 。
你需要将 intervals 划分为一个或者多个区间 组 ,每个区间 只 属于一个组,且同一个组中任意两个区间 不相交 。
请你返回 最少 需要划分成多少个组。
如果两个区间覆盖的范围有重叠(即至少有一个公共数字),那么我们称这两个区间是 相交 的。比方说区间 [1, 5] 和 [5, 8] 相交。
示例 1:
输入:intervals = [[5,10],[6,8],[1,5],[2,3],[1,10]] 输出:3 解释:我们可以将区间划分为如下的区间组: - 第 1 组:[1, 5] ,[6, 8] 。 - 第 2 组:[2, 3] ,[5, 10] 。 - 第 3 组:[1, 10] 。 可以证明无法将区间划分为少于 3 个组。
示例 2:
输入:intervals = [[1,3],[5,6],[8,10],[11,13]] 输出:1 解释:所有区间互不相交,所以我们可以把它们全部放在一个组内。
提示:
1 <= intervals.length <= 105intervals[i].length == 21 <= lefti <= righti <= 106
1.模拟,先按左边界对序列进行排序,之后进行多次便历,每次遍历后去删除一组不相交的区间,当序列为空时,遍历次数即为最小组数。(On^2,会超时)
1 class Solution { 2 public: 3 multimap<int,int> range; 4 int minGroups(vector<vector<int>>& intervals) { 5 for(auto i : intervals){ 6 range.insert(make_pair(i[0], i[1])); 7 } 8 int num = 0; 9 while(!range.empty()){ 10 num++; 11 int right = 0; 12 for (auto it = range.begin(); it != range.end(); ){ 13 if (it->first > right){ //表示不相交 14 right = it->second; 15 it = range.erase(it); 16 }else{ 17 it++; 18 } 19 } 20 } 21 return num; 22 } 23 };
2.贪心
这个贪心策略不太好想,依旧先对原序列进行排序,我们使用一个优先队列来存放每组中的最右边界,比如[1, 5] ,[6, 8] 这一组中,我们只存储最右边界8作为这一组存在的标志,队列的头部存放最大的右边界值max。只要存在一个区间[a,b],左边界a比max大,就说明这个区间可以加入到优先队列中的任何一组。贪心策略就体现在这里,我们始终把区间[a,b]加入到以max为最右边界的那一组,这样我们的b就成为了新的最大右边界值。当遍历所有区间以后,优先队列中的元素数量就是最小组数。
1 class Solution { 2 public: 3 priority_queue<int, vector<int>, greater<int>> group; //用来存储每组中的最右边界 4 int minGroups(vector<vector<int>>& intervals) { 5 sort(intervals.begin(),intervals.end()); 6 for(auto i : intervals){ 7 if (!group.empty() && i[0] > group.top()){ 8 group.pop(); 9 } 10 group.push(i[1]); 11 } 12 return group.size(); 13 } 14 };
3.该题还有线段树和差分数组的解法
浙公网安备 33010602011771号