代码随想录算法训练营第34天 | 860.柠檬水找零 406.根据身高重建队列 452. 用最少数量的箭引爆气球

860.柠檬水找零

        做题做多了,会有种把简单问题想复杂的感觉,这道题其实很简单,只需统计5元和10元的张数就行,就像现实生活中的收银柜,模拟收银的过程就行了。假设客户给了5元,咱们收下,5元的数量加一,假设客户给了10元,咱们就得判断柜子里还有没有5元,有的话就把5元找给客户,假设客户给了20元,那么现在有两种方案,一个是找回一张10元和一张5元,一个是找回3张元,咱们优先考虑第一种方案,因为5元更通用,而10元只能找20元的,所以咱们 要尽可能保留5元。

https://leetcode.cn/problems/lemonade-change/submissions/505522797/

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five=0;int ten=0;
        for(int i=0;i<bills.size();i++)
        {
            if(bills[i]==5)
            five++;
            else if(bills[i]==10)
            {
                if(five>0)
                {five--;
                ten++;
                }
                else
                return false;
            }
            else
            {
                if(five>0&&ten>0)
                {
                    five--;
                    ten--;
                }
                else if(five>=3)
                {
                    five-=3;
                }
                else
                return false;
            }
        }
        return true;
    }
};

406.根据身高重建队列

        这道题看到的时候会觉得很绕,关键点在于这道题给的是两个维度,一个是身高,一个是前面比‘我’高的人的个数,假如我们按照前面比我高的个数来排会找不到规律,但是如果按照身高从大到小排,那么我们可以发现这时候只需根据前面比我高的个数来将人的属性挪到对应的位置就可以,因为是从大到小排的,所以不用担心后面的挪到前面来,会导致前面的个数与之不匹配,因为个数是比我高的个数,而比我矮的挪到我前面来,根本不影响我的“前面比我高的个数”。

class Solution {
private:
    static bool cmp(vector<int>&a,vector<int>&b)
        {
            if(a[0]==b[0])
            return a[1]<b[1];
            return a[0]>b[0];
        }
public:
    // vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
    //     sort(people.begin(),people.end(),cmp);
    //     vector<vector<int>>queue;
    //     for(int i=0;i<people.size();i++)
    //     {
    //         int pos=people[i][1];
    //         queue.insert(queue.begin()+pos,people[i]);
    //     }
    //     return queue;
    // }
       vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(),people.end(),cmp);
        list<vector<int>>queue;
        for(int i=0;i<people.size();i++)
        {
            int pos=people[i][1];
            list<vector<int>>::iterator it=queue.begin();
            while(pos--)
            {
                it++;
            }
            queue.insert(it,people[i]);
        }
        return vector<vector<int>>(queue.begin(),queue.end());
    }
};

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

        Carl哥真是我的神,我觉得这道题最关键的是得把图画出来,按照左区间从小往大的顺序我们观察图会理解得透彻一些,我们按照左区间从小到大,那么比较的时候就需要判断这个区间的左区间与上一个区间的右区间的大小,如果比上一个小,那么说明有重叠部分,所以可以共用一支箭,那我们还要判断后面的是否能跟这两个公用一支呢,这时候关键点在于把现在这个区间的右区间更新为这个区间的右区间和上一个区间的右区间的最小值,因为这样的话下一个区间的左区间与现在这个区间的右区间比较,如果比现在的小,那么说明有重叠部分,还是按照同样的套路更新右区间,如果比现在的大,说明又要多一支箭了(因为没有重叠部分)。

https://leetcode.cn/problems/minimum-number-of-arrows-to-burst-balloons/submissions/505686548/

class Solution {
private:
    static bool cmp(vector<int>&a,vector<int>&b)
    {
        return a[0]<b[0];
    }
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        if(points.size()==0) return 0;
        sort(points.begin(),points.end(),cmp);
        int result=1;
        for(int i=1;i<points.size();i++)
        {
            if(points[i][0]>points[i-1][1])
            result++;
            else
            points[i][1]=min(points[i-1][1],points[i][1]);
        }
        return result;
    }
};

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值