区间问题,我们需要根据题意,其判断以区间左边界还是右边界为指标,进行排序,然后从第一个开始,观察什么时候符合题目要求,什么时候更新位置。
排序:
//对二维数组进行排序
sort(begin(points), end(points),
[](const vector &o1, const vector &o2) {
return (o1[1] < o2[1]);
});
多条件排序:
//按照身高降序,但是身高相同时,我们按照位置升序
sort(begin(people),end(people),[]
(const vector & o1,const vector & o2)
{return o1[0] == o2[0]?o1[1] <= o2[1]:o1[0] > o2[0];});
就排序,我们再看看相关的内容:
class Solution {
public:
string largestNumber(vector& nums) {
if(nums.empty()) return "";
vector temp;
for(auto item:nums) temp.push_back(to_string(item));
sort(begin(temp),end(temp),[](const string & o1,const string & o2)
{return o1+o2>o2+o1;}
);
string Res;
for(auto item:temp) Res += item;
//提出多余的0
int begin = 0;
while(begin
此类型的题目,核心就是排序这一句话
sort(begin(temp),end(temp),[](const string & o1,const string & o2)
{return o1+o2>o2+o1;}
);
剑指 Offer 45. 把数组排成最小的数
class Solution {
public:
string minNumber(vector& nums) {
vector Temp;
for(auto item:nums) Temp.push_back(to_string(item));
sort(begin(Temp),end(Temp),[](const string & o1,const string & o2)
{return o1+o2Res.size()&&Res[begin] == '0') begin++;
if(begin == Res.size()) return "0";
Res = Res.substr(begin,Res.size()-begin);
return Res;
}
};
合理运用排序
字符串排序:
sort(begin(temp),end(temp),[](const string & o1,const string & o2)
{return o1+o2>o2+o1;}//降序,大的在前面
);
目录
区间问题
求相交区间
452. 用最少数量的箭引爆气球
435. 无重叠区间
合并重复区间
56. 合并区间
计算最多几个区间重叠
253. 会议室 II
406. 根据身高重建队列
https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/
参考解答:
https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/solution/tan-xin-suan-fa-python-dai-ma-by-liweiwei1419/
https://leetcode-cn.com/problems/minimum-number-of-arrows-to-burst-balloons/solution/yong-zui-shao-shu-liang-de-jian-yin-bao-qi-qiu-b-2/
面对区间相交问题,我们一般想到的是先排序,完成排序后,我们再进行筛选符合题意的内容
一般排序是按照什么样的方式呢?以区间的开头吗?如果区间很长,开始的早结束的晚,和其他区间的覆盖面积就很大
一般会选择以区间结尾升序排列,然后不断更新。
下面两道题目非常相似,都是关于区间问题的。
class Solution {
public:
int findMinArrowShots(vector>& points) {
int size = points.size();
if(size == 0) return 0;
//按照要求排序(按照末尾元素大小进行排序)
sort(begin(points), end(points),
[](const vector &o1, const vector &o2) {
return (o1[1] < o2[1]);
});
int Res = 1;
int begin = 0,end = 0,FristEnd = points[0][1];
for(auto item:points)
{
begin = item[0];end = item[1];
if(FristEnd
https://leetcode-cn.com/problems/non-overlapping-intervals/
class Solution {
public:
int eraseOverlapIntervals(vector>& intervals) {
if(intervals.empty()) return 0;
sort(begin(intervals), end(intervals),
[](const vector &o1, const vector &o2) {
return (o1[1] < o2[1]);
});//
int size = 0;
int Begin = 0,End = 0;
int FristEnd = intervals[0][1];
for(int i = 1;i
https://leetcode-cn.com/problems/merge-intervals/submissions/
本题不同于上面两道题目,需要以区间的首个元素,也就是区间的左极限为指标,进行排序。
因为有特殊情况的存在:
我们需要维护一个区间右极限最大值,一旦新的区间左值小于这个极限值,说明有交集,说明要合并数组
完整代码如下:
class Solution {
public:
vector> merge(vector>& intervals) {
if(intervals.empty()) return {};
vector>Res;
sort(begin(intervals),end(intervals),
[](const vector& P1,const vector& P2)
{return P1[0] Temp(2,0);
Temp[0] = INT_MAX,Temp[1] = INT_MIN;//因为要比大小,此处初值需要特别设置
int end = intervals[begin][1];//记录
while(begin+1<=size-1&&end>=intervals[begin+1][0])//可以合并
{
cout<
https://leetcode-cn.com/problems/meeting-rooms-ii/
算法参考:https://leetcode-cn.com/problems/meeting-rooms-ii/solution/253-hui-yi-shi-ii-c-shang-xia-che-wen-ti-by-gao-yu/
本质是求同时重叠的区间个数的最值
根据算法参考:我们把这个过程理解为上下车
开会开始时间就是上车,开会结束时间就是下车,最大重叠区间就是在车上人数最多的时候
上下车版本:记录开会的开始时间结点,记录开会的结束时间结点
上车就增加人,下车就是减少人,看看这个过程中什么时候人最多
我们只关心开会的开始时间和结束时间,分别按照开始和结束时间升序排序,如此才能看得出会议使用情况!
新会议的开始时间,大于旧会议的结束时间,说明新会议开始前,旧会议已经结束,会议室有空闲
其余情况就是旧会议还没结束,新会议已经开始,那么必然要再次开辟新的房间
完整代码如下:
class Solution {
public:
int minMeetingRooms(vector>& intervals) {
//典型的区间问题
if(intervals.empty()) return 0;
//按照开始时间排序-升序
sort(begin(intervals),end(intervals),[]
(const vectoro1,const vectoro2){return o1[0]>(intervals.begin(), intervals.end());
sort(begin(intervals_end),end(intervals_end),[]
(const vectoro1,const vectoro2){return o1[1]= intervals_end[e_point][1])
{
used_room --;//有会议结束,减少房间
e_point++;//查看下一个结束时间点
}
//其余情况就是旧会议还没结束,新会议已经开始,那么必然要再次开辟新的房间
// intervals[s_point][0] < intervals_end[e_point][1]
used_room ++;
s_point ++;
MAX = max(MAX,used_room);
}
return MAX;
}
};
https://leetcode-cn.com/problems/queue-reconstruction-by-height/
算法参考:https://leetcode-cn.com/problems/queue-reconstruction-by-height/solution/gen-ju-shen-gao-zhong-jian-dui-lie-by-leetcode/
还是找规律的问题,首先排身高高的人,按照身高高低,降序排列。
身高相同,按照位置升序。
完成排列后,我们开始插入工作:
每个人在新队列中的位置(索引),就是他本身的位置,我们第一步排序只是为了更好的按照顺序插入:
整个过程如上:我们排序是为了后续按照顺序插入。
class Solution {
public:
vector> reconstructQueue(vector>& people) {
if(people.empty()) return {};
//按照身高降序,但是身高相同时,我们按照位置升序
sort(begin(people),end(people),[]
(const vector & o1,const vector & o2)
{return o1[0] == o2[0]?o1[1] <= o2[1]:o1[0] > o2[0];});
int size = people.size();
vector>Res;
// 循环插入
for(int i = 0; i < size; ++i)
{
Res.insert(Res.begin() + people[i][1], people[i]);//此时务必使用插入,而不是替换
}
return Res;
}
};
下面的解释对理解本题很有帮助: