🌹作者:云小逸
📝个人主页:云小逸的主页
📝Github:云小逸的Github
🤟motto:要敢于一个人默默的面对自己,==强大自己才是核心==。不要等到什么都没有了,才下定决心去做。种一颗树,最好的时间是十年前,其次就是现在!学会自己和解,与过去和解,努力爱自己。==希望春天来之前,我们一起面朝大海,春暖花开!==🤟 👏专栏:C++👏 👏专栏:Java语言👏👏专栏:Linux学习👏
👏专栏:C语言初阶👏👏专栏:数据结构👏👏专栏:备战蓝桥杯👏
@TOC
前言
今天我们继续学习算法,加油。这篇文章写的是最大不相交区间数量问题,使用了贪心思想。希望这篇可以有幸帮助到你,码字不易,请多多支持。
——————————————————————————————
题目描述
给定 个闭区间 ,请你在数轴上选择若干区间,使得选中的区间之间互不相交(包括端点)。输出可选取区间的最大数量。
输入格式
第一行包含整数 ,表示区间数。
接下来 行,每行包含两个整数 和 ,表示一个区间的两个端点。
输出格式
输出一个整数,表示可选取区间的最大数量。
数据范围
,
输入样例
3
-1 1
2 4
3 5
输出样例
2
思路分析
贪心是本题最常见的思路。考虑按照右端点排序,从前往后依次选取右端点最小的区间,同时删去与它相交的所有区间,重复该过程直到所有区间都被删完。由于每次选择的区间都是右端点最小的,所以该算法具有最优子结构性质,即每次选择的区间都是局部最优的,因此最终的结果也是全局最优的。
为了实现该算法,可以使用 STL 中的 sort() 函数对区间按右端点排序,然后从前往后扫描每个区间,若该区间与前面已经选取的区间不相交,则选取该区间,并将其右端点设为当前右端点。否则,忽略该区间并继续扫描下一个区间。
代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Segment {
int l, r;
bool operator<(const Segment &seg) const {
return r < seg.r;
}
} seg[N];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> seg[i].l >> seg[i].r;
}
sort(seg, seg + n);
int cnt = 0, r = -1;
for (int i = 0; i < n; i++) {
if (seg[i].l > r) {
cnt++;
r = seg[i].r;
}
}
cout << cnt << endl;
return 0;
}
时间复杂度分析
时间复杂度主要来自排序操作,为 。
空间复杂度分析
只使用了常数个变量,空间复杂度为 。
完整代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
struct Segment {
int l, r;
bool operator<(const Segment &seg) const {
return r < seg.r;
}
} seg[N];
int main() {
int n;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> seg[i].l >> seg[i].r;
}
sort(seg, seg + n);
int cnt = 0, r = -1;
for (int i = 0; i < n; i++) {
if (seg[i].l > r) {
cnt++;
r = seg[i].r;
}
}
cout << cnt << endl;
return 0;
}
最后
十分感谢你可以耐着性子把它读完和我可以坚持写到这里,送几句话,对你,也对我:
1.把时间尺度拉长,拉长十年看当下
2.不说负面情绪,只描述事实;
3.越专注于过好自己,能量和幸运越会照顾你;
只解决问题,不做没有意义的担心,输了就认;
4.学会原谅自己,要允许自己做错事,允许自己出现情绪波动,我知道你已经很努力很努力在做好了
5.所有你害怕的、想逃避的事情,最终都要面对,既然这样不如选择坦然面对。即使结果不如人愿,没关系,至少这个过程是享受的,而不是一路带着恐惧和害怕。
最后如果觉得我写的还不错,请不要忘记==点赞==✌,==收藏==✌,加==关注==✌哦(。・ω・。)
愿我们一起加油,奔向更美好的未来,愿我们从懵懵懂懂的一枚==菜鸟==逐渐成为==大佬==。加油,为自己点赞!