【C++编程能力提升】

一、860 柠檬水找零

题目链接:860 柠檬水找零

核心:只有三种情况,第一,收到一张5,则直接收下;第二,收到一张10,需退还一张5;第三,收到一张20,需退还15,优先选择退还一张10和一张5,若没有10则退还3张5,否则无法退还。

    bool lemonadeChange(vector<int>& bills) {
        //分3种情况:
        int five=0,ten=0,twenty=0;
        for(int bill:bills)
        {
            if(bill==5)
                five++;
            else if(bill==10)
            {
                if(five<=0)
                    return false;   //没有5无法退还
                ten++;  //收了一张10,同时退还一张5
                five--;
            }
            else
            {
                if(five>0 && ten>0)
                {//目前已有10和5,优先退还一张10和一张5
                    ten--;
                    five--;
                    twenty++;
                }
                else if(five>=3)
                {//目前没有10,只有5,且至少有3张5,则退还3张5
                    five-=3;
                    twenty++;
                }
                else 
                    return false;   //无法退还
            }
        }
        return true;
    }

二、406 根据身高重建队列

题目链接:406 根据身高重建队列

核心:重点是先按照身高从大到小进行排列,然后从前往后遍历,根据排在前面的的人的数值依次插入到相应的索引位置。
注意:利用链表构造重排队列比vector大大减少操作的复杂度。

    static bool cmp(const vector<int>& a,const vector<int>& b)
    {
        if(a[0]==b[0])
            return a[1]<b[1];   //第一维度元素值相等时,按照第二维从小到大排列
        return a[0]>b[0];   //按照第一维从大到小排列
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        //先按身高排序,再根据身高从大到小的对应人数(即索引)逐个插入
        sort(people.begin(),people.end(),cmp);
        //vector<vector<int>> res;    //记录排序后的二维数组
        list<vector<int>> res;  //使用链表非vector进行插入操作
        for(int i=0;i<people.size();++i)
        {//按照每个人的第二维数值重新插入
            int index=people[i][1]; //每个人排在前面的人
            //res.insert(res.begin()+index,people[i]);    
            list<vector<int>>::iterator it=res.begin(); //res第一个元素的迭代器
            while(index--)
                it++;   //迭代器移动到index位置,在此处插入
            res.insert(it,people[i]);
        }
        return vector<vector<int>> (res.begin(),res.end());
    }

三、452 用最少数量的箭引爆气球

题目链接:452 用最少数量的箭引爆气球

核心:最少数量的箭意味着重叠区间只使用一个,不重叠区间才开始增加箭数。
首先要按照起始位置进行排序,排序后寻找下一个元素的起始位置大于当前元素的结束位置,说明区间无法重叠,需要增加箭数;否则说明存在重叠区间,此时需要更新重叠区间的结束位置,即当前元素结束位置和上一个结束位置的最小值。

    static bool cmp(const vector<int>& a,const vector<int>& b)
    {//排序函数,按照第一个数从小到大排列(意味着需要从前往后遍历)
        return a[0]<b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.size()==0)
            return 0;
        sort(points.begin(),points.end());
        int res=1;  //记录所需的最小弓箭数,只要points不为空至少需要1个弓箭,故初始化为1
        for(int i=1;i<points.size();++i)
        {
            if(points[i][0]>points[i-1][1])
                res++;  //当前元素起始坐标大于上一个元素的结束坐标(也可能是上上一个),需增加弓箭
            else    //起始坐标小于等于上一个的结束坐标,即存在重叠区间,此时更新结束坐标
                points[i][1]=min(points[i][1],points[i-1][1]);   //只能是最小值
        }
        return res;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值