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

目录

题目连接:860.柠檬水找零

思路

代码

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

思路

代码

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

思路

代码

总结


题目连接:860.柠檬水找零

思路

        找零会出现以下情况:

        ①5美元,直接收下

        ②10美元,找一个5美元

        ③20美元,找一个10美元和一个5美元;或者找三个5美元

        也就是说只有②③情况会出现找不开的情况,所以只需要在遍历bills数组时,不断记录5美元和10美元的数量即可。如果遍历完数组没有出现5美元和10美元数量不够的情况,就说明能够找开。题目不难,只要分析清楚上述三种情况即可。

代码

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0; // 记录五美元的数量
        int ten = 0;  // 记录十美元的数量
        for (int a : bills) {
            // 五美元直接收下,数量加一
            if (a == 5) {
                five++;
            }
            // 十美元,要找五美元
            else if (a == 10) {
                // 没有五美元可找了,返回false
                if (five <= 0)
                    return false;
                five--;
                ten++;
            }
            // 二十美元,首先判断能否找十美元和五美元
            // 如果不行,就找三个五美元
            // 只有上述两种情况,如果都不行就说明找不开
            else if (a == 20) {
                // 因为十美元只能找二十美元,所以优先判断
                if (ten >= 1 && five >= 1) {
                    ten--;
                    five--;
                } else if (ten <= 0 && five >= 3) {
                    five -= 3;
                } else
                    return false;
            }
        }
        return true;
    }
};

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

思路

        有两个维度,身高h和前面身高大于等于自己身高的人数k,一定要先确定一个维度,然后用另一个维度来进行排序。

        选定身高为第一个维度,让所有人按照从高到低的顺序排列,如果身高相同则k小的人站在前面。这样就一定能保证前面的人不比后面的人矮。

        然后按照k进行排序,因为已经按照身高排序,此时k是多少,就让他前面站几个人即可。

代码

class Solution {
public:
    // 定义排序规则,按h从大到小,h相等的人,k小的在前面
    static bool cmp(const vector<int>& a, const vector<int>& b) {
        if (a[0] == b[0])
            return a[1] < b[1]; // k小的在前面
        return a[0] > b[0];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), cmp); // 按身高排序
        list<vector<int>> que; // list底层实现是链表,插入元素时间复杂度低
        for (int i = 0; i < people.size(); i++) {
            int position = people[i][1]; // k值即位置
            auto it = que.begin();
            // 找到列表中插入元素的位置
            while (position--) {
                it++;
            }
            que.insert(it, people[i]); // 插入元素
        }
        // 按照函数返回类型返回结果
        return vector<vector<int>>(que.begin(), que.end());
    }
};

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

思路

        需要注意的是每个气球的区间更新问题,具体见代码注释

代码

class Solution {
public:
    // 定义排列规则,按照起始位置,从小到大
    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(), cmp); // 排序
        int result = 1; // 有气球,则最少一支箭
        for (int i = 1; i < points.size(); i++) {
            // 当前气球的起点大于上一个气球的终点
            if (points[i][0] > points[i - 1][1]) {
                result++;
            }
            // 如果两个气球挨着或者重叠,则更新当前气球的终点为最小的右边界
            // 如果不更新,则会出现1和2重叠,2和3重叠,但是1和3不重叠
            // 只记录一支箭的情况,实际应该是需要两支
            //
            else {
                points[i][1] = min(points[i][1], points[i - 1][1]);
            }
        }
        return result;
    }
};

总结

        ①贪心算法已经做了一些题了,但遇到新题时还是没有明确的思路,多练多复习

        ②双维度排列问题,需要逐步分析,不可一起考虑

        ③重叠区间问题,注意区间的更新

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值