算法学习 | day30/60 柠檬水找零/根据身高重建队列/用最少数量的箭引爆气球

本文介绍了三个LeetCode编程题目,涉及找零算法、根据身高重建队列(排序和队列操作)以及用最少箭矢引爆气球(重叠区间处理)。展示了如何运用清晰的思路和数据结构解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、题目打卡

        1.1 柠檬水找零

        题目链接:. - 力扣(LeetCode)

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        // int rest = 0;
        unordered_map<int,int> rest;
        for(auto &it : bills){
            int tmp = it - 5;
            rest[it]++;
            while(tmp / 20 && rest[20] != 0){
                tmp -= 20;
                rest[20]--;
            }
            while(tmp / 10 && rest[10] != 0){
                tmp -= 10;
                rest[10]--;
            }
            while(tmp / 5 && rest[5] != 0){
                tmp -= 5;
                rest[5]--;
            }
            if(tmp > 0) return false;
            // int tmp = it - 5; // 找零的钱
            // rest += it;
            // rest -= tmp;
            // if(rest < 0) return false;
        }
        return true;
    }
};

        模拟收银台的方式进行找零,这样不过多浪费了一些空间,但是思路还是很清楚的,从最大的向最小的开始找零。

        1.2 根据身高重建队列

        题目链接:. - 力扣(LeetCode)​​​​​​​

class Solution {
public:
    static bool myCompare(const vector<int>& v1, const vector<int>& v2) {
        if(v1[0] == v2[0]) return v1[1] < v2[1];
        return v1[0] > v2[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), myCompare);
        // for (auto &i : people) {
        //     cout << i[0] << " " << i[1] << endl;
        // }
        vector<vector<int>> res;
        for(auto &i : people){
            res.insert(res.begin() + i[1], i);
        }
        return res;
    }
};

        题目和分发糖果的思路很相似,都是固定一个条件去考虑另一个条件,这里先根据身高对整个队列进行排序,然后比较巧妙的思路是排序后的队列,只需要根据当前值的索引1就是需要插入到最后的位置,这里有个小的细节是,写谓词的时候,注意写在 class 里的话,需要前面加 static,另一个就是谓词的处理逻辑,需要加上一个身高相等情况下索引2升序排列的情况,否则最后答案会出现错误。

        1.3 用最少数量的箭引爆气球

        题目链接:. - 力扣(LeetCode)

class Solution {
public:
    static bool cmp(vector<int>& v1, vector<int>& v2){
        if(v1[0] == v2[0]) return v1[1] < v2[1];
        return v1[0] < v2[0];
    }
    int findMinArrowShots(vector<vector<int>>& points) {
        sort(points.begin(),points.end(),cmp);
        // for (auto &i : points) {
        //     cout << i[0] << " " << i[1] << endl;
        // }
        // int res = 0;
        // for(int i = 0; i < points.size();i++){
        //     res++;
        //     int tmp = points[i][1];
        //     while(i < points.size() - 1 && tmp >= points[i + 1][0]){
        //         i++;
        //     }
        // }


        int res = 1;
        vector<int> tmp{INT_MIN,INT_MAX};
        for(int i = 0 ; i < points.size() ; i++){
            if(tmp[1] < points[i][0]){
                res++;
                tmp = {INT_MIN,INT_MAX};
            }
            tmp[0] = max(points[i][0], tmp[0]);
            tmp[1] = min(points[i][1], tmp[1]);
        }
        return res;
    }
};

        考察的是重叠区间的处理,处理时的思路是对左端点进行排序,然后动态维护一个坐标,这个左边是实时进行更新的,当发现如果循环过程中的某个左索引超过了维护数组的右索引,那么就说明一根箭已经无法穿过了,这时候就需要重置坐标,并把最后返回箭的数目加1。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值