关于刷题的一些想法以及sort以及priority_queue优先队列的使用

1. 在函数中的形参为引用的形式可以大大的提升时间。增幅接近一倍!!!而且也大大的节省了空间!!!

就算是字符串类型也是一样,字符串传参主要是地址的传入,计算机依旧申请了空间,这样就加大了内存的使用,并且减慢的速度。

2. 在元素有规律的数据结构中进行查找,可以采用一边比较一边排序的方法。

因为这种情况的特殊性,可以在结构取一种中间值,与目标值进行比较,如果等于目标值则找到答案,
有两个值i和j可以来调节值的大小,如果大于则调节i和j来增大中间值,小于则调小、

3. 一个可以分为许多有联系的子集的问题时可以用动态规划来解决

有一种递推关系在里面,分成许多个子集,而且子集之间能够找到一种对应的关系,答案的形式并不固定,有时候可能让你选最大值,有时候是一个vector,有时候是最小值,但是在解决问题的过程中如果出现了考虑子集的流程,出现了将一个大问题分为很多小问题的想法,就不要在多想了,dp吧少年!!!

4. 关于sort函数以及优先队列priority_queue的用法

sort 函数包括在头文件为algorithm中,它的参数主要为

void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);
其中first和last为数据的起始地址(迭代器),第三个的comp则是自定义的 比较方式
一般采用三种方法
1 重载小于操作符
对于operator<(a,b)来说,该重载函数的返回值必定是a<b,按照我们前面说的,如果返回值为true,那么就把a放在b前面,也就是说,如果a<b,那么a在排序后序列中是在b前面的,而这一点恰好印证了sort函数的默认排序方式为升序。为了更好的理解这一点,我们来用另一种方式来重载小于号:(重载的方式有多种,可见)

struct stu
{
    string name;
    int num;
    int age;
 
    bool operator<(const stu &p)const
    {
        return age<p.age;
    }
}S[5];
 
int main(int argc, char *argv[])
{
    S[0]={"aa",1,10};
    S[1]={"bb",2,9};
    S[2]={"cc",3,8};
    S[3]={"dd",4,7};
    S[4]={"ee",5,6};
 
    sort(S,S+5);
 
    for(auto s:S)
        cout<<s.name<<" ";
 
    return 0;
}

在这段程序中,小于号重载为比较两个结构体的成员变量(age)的大小,如果第一个参数的age较小,那么就将该结构体变量放在排序序列的前面。

2 自定义cmp函数

struct stu
{
    string name;
    int num;
    int age;
}S[5];
 
bool cmp(const stu &q,const stu &p)
{
    return q.num<p.num;
}
int main(int argc, char *argv[])
{
    S[0]={"aa",1,10};
    S[1]={"bb",2,9};
    S[2]={"cc",3,8};
    S[3]={"dd",4,7};
    S[4]={"ee",5,6};
 
    sort(S,S+5,cmp);
 
    for(auto s:S)
        cout<<s.name<<" ";
 
    return 0;
}

值得注意的是,在同一份类中定义cmp函数,应该在cmp函数前添加static使它变为一个静态函数,不用实例就能调用。
3 自定义仿函数

struct stu
{
    string name;
    int num;
    int age;
}S[5];
 
struct cmp
{
    operator ()(const stu &q,const stu &p)
    {
        return q.num>p.num;
    }
};
 
int main(int argc, char *argv[])
{
    S[0]={"aa",1,10};
    S[1]={"bb",2,9};
    S[2]={"cc",3,8};
    S[3]={"dd",4,7};
    S[4]={"ee",5,6};
 
    sort(S,S+5,cmp());
 
    for(auto s:S)
        cout<<s.name<<" ";
 
    return 0;
}

这里相当于重载了小括号操作符,是的类也可以添加()像函数一样使用,故称为仿函数。因为此处将较大的放在前面,因为是按照从大到小排序的。sort调用时要加上括号

priority_queue包在头文件为queue中,它的参数主要为

priority_queue<Type, Container, Functional>

其中Type是基础的数据类型,Container是容器类别(相当于是底层队列是用的底层容器),Funcitional是比较的方式。使用基本数据类型是,只需要传入数据类型,就是大顶堆。写priority_queue的比较函数有两种方法

1. 重载小于操作符

struct stu
{
    string name;
    int num;
    int age;
 
    bool operator<(const stu &p)const
    {
        return age>p.age;
    }
}S[5];
 
int main(int argc, char *argv[])
{
    S[0]={"aa",1,10};
    S[1]={"bb",2,9};
    S[2]={"cc",3,8};
    S[3]={"dd",4,7};
    S[4]={"ee",5,6};
    priority_queue<stu>q; 
    for(int i=0;i<5;i++)q.push(S[i]);
 
    while(!q.empty())
    {
        cout<<q.top().name<<" ";
        q.pop();
    }
 
    return 0;
}

大的数在前面,因此是从大到小排序

2. 自定义仿函数

struct stu
{
    string name;
    int num;
    int age;
}S[5];
 
struct cmp
{
    operator ()(const stu &q,const stu &p)
    {
        return q.num<p.num;
    }
};
 
int main(int argc, char *argv[])
{
    S[0]={"aa",1,10};
    S[1]={"bb",2,9};
    S[2]={"cc",3,8};
    S[3]={"dd",4,7};
    S[4]={"ee",5,6};
 
    priority_queue<stu,vector<stu>,cmp >q;
 
    //priority_queue<stu>q;
 
    for(int i=0;i<5;i++)q.push(S[i]);
 
    while(!q.empty())
    {
        cout<<q.top().name<<" ";
        q.pop();
    }
 
    return 0;
}

这里的cmp是按num的从小到大进行排列,然后从末尾(优先级最高)开始弹出

leetcode218,天际线问题,使用优先队列

class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        vector<vector<int>> ans;
        priority_queue<pair<int,int>> maxs;
        //优先队列会自动找到最高的值
        int i = 0, n = buildings.size();
        //此处的n为建筑物的数量
        int cur_x, cur_h;
        while(i < n||!maxs.empty()){//当i<n或者优先队列不为空时
            if(maxs.empty()||i < n&&maxs.top().second >= buildings[i][0]){
                //当优先队列为空或者最大高度建筑的右值大于此时建筑的左值,也就是说出现交叉时
                cur_x = buildings[i][0];
                while(i < n&&cur_x == buildings[i][0]){
                    maxs.emplace(buildings[i][2], buildings[i][1]);
                    ++i;
                }//当有交叉时,左值作为输入
            } else {
            //当当前的最高建筑与下一个建筑没有交叉时,考虑考当前建筑的落幕,选取他的右值作为输入,并且此时将多余的弹出去。
                cur_x = maxs.top().second;
                while(!maxs.empty()&&cur_x >= maxs.top().second){
                    maxs.pop();//将右值在当前最高建筑的右值之前的建筑都弹出队列,因为这些建筑都不会对天际线产生影响
                }
            }
            cur_h = maxs.empty()? 0:maxs.top().first;//为空的时候就代表着上一个建筑群已经全部计算结束。落幕的高度为0
            if(ans.empty()||cur_h != ans.back()[1]){
                ans.push_back({cur_x, cur_h});
            }
        }
        return ans;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值