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

参考

代码随想录

题目一:LeetCode 860.柠檬水找零

这个题在做的时候有误解,第一不能对数组bills排序,只能按照给定的顺序处理;第二,只能从头开始处理,不能中间的某个点开始。
其实这个题很简单,无非就三种情况:

  • 第一,5美元,直接收下;
  • 第二,10美元,找5美元;
  • 第三,20美元,优先找10+5美元,如果没有,则找5+5+5美元

对于第二和第三种情况,如果不能找零,直接返回false。代码实现如下:

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

代码中不用记录20出现的次数。

题目二:LeetCode 406.根据身高重建队列

这个题和135. 分发糖果很类似,都是涉及到两个维度。在涉及到两个维度时,先确定一个维度,再确定另一个维度,如果两个维度一起确定到顾此失彼。
本题先根据hi对数组从小到大进行排列,然后再根据ki进行插值。
例如people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]],排序后 people = [[7,0],[7,1],[6,1],[5,0],[5,2],[4,4]]
插入[7,0]:[[7,0]]
插入[7,1]:[[7,0],[7,1]]
插入[6,1]:[[7,0],[6,1],[7,1]]
插入[5,0]:[[5,0],[7,0],[6,1],[7,1]]
插入[5,2]:[[5,0],[7,0],[5,2],[6,1],[7,1]]
插入[4,4]:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]

在代码实现上,为提高效率,插值过程使用链表而不是用数组vector。

class Solution {
public:
    //按照身高从大到小排列(身高相同k小的站前面)
    static bool cmp(vector<int> a, 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) {
        list<vector<int>> que;
        sort(people.begin(),people.end(),cmp);
        for(int i = 0; i < people.size(); i++){
            int index = people[i][1];
            auto it = que.begin();
            while(index--)  it++;
            que.insert(it,people[i]);
        }
        return vector<vector<int>>(que.begin(),que.end());
    }
};

题目三:LeetCode 452. 用最少数量的箭引爆气球

这个题的一个思路是将区间按照左边界的大小从小到大进行排序,然后以此合并区间,合并区间指的是两个区间用公共区间来代替,如果没有公共区间就不合并。在代码实现上不用真正的去合并区间,只需要不断更新有公共区间的最小右边界值即可,每一个最小的公共右边界对应一支箭;如果没有重叠区间,每一个区间就需要一支箭。
在这里插入图片描述
代码实现如下:

class Solution {
public:
    static bool cmp(vector<int>& a, vector<int>& b)
    {
        return a[0] < b[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        int result = 1;  //最后退出的时候要加1
        sort(points.begin(),points.end(),cmp);
        for(int i = 0; i < points.size()-1; i++){
            if(points[i+1][0] > points[i][1])  //这里不能包含等号
                result++;
            else
                points[i+1][1] = min(points[i][1],points[i+1][1]);
        }
        return result;
    }
};

注意,自定义的比较函数cmp的参数要使用传引用的方式,一开始用的是传值,这样会导致超时。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忆昔z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值