day34打卡

day34打卡

860. 柠檬水找零

解法,贪心:局部最优:遇到账单20,优先消耗美元10,完成本次找零 -》全局最优:完成全部账单的找零。

  • 遇到5,直接收下
  • 遇到10,找一个5元
  • 遇到20,优先找一张10和一张5,没有10元,找3张5元
class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int five = 0, ten = 0, twenty = 0;
        for(auto& e : bills)
        {
            //情况1
            if(e == 5) five++;
            //情况2
            if(e == 10)
            {
                if(five == 0) return false;
                five--;
                ten++;
            }
            //情况3
            if(e == 20)
            {
                if(five > 0 && ten > 0)
                {
                    five--;
                    ten--;
                    twenty++;
                }
                else if(five >= 3)
                {
                    five -= 3;
                    twenty++;
                }
                else
                {
                    return false;
                }
            }
        }
        return true;
    }
};

406. 根据身高重建队列

解法,贪心:局部最优:优先按身高高的people的k来插入。插入操作过后的people满足队列属性 -》全局最优:最后都做完插入操作,整个队列满足题目队列属性

  • 身高从大到小排(身高相同k小的站前面)

day34打卡_第1张图片

class Solution {
    // 身高从大到小排(身高相同k小的站前面)
    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];
    }
public:
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), cmp);
        // list底层是链表实现,插入效率比vector高的多
        list<vector<int>> queue;
        for(int i = 0; i < people.size(); i++)
        {
            int pos = people[i][1];//插入位置的下标,也就是k
            std::list<vector<int>>::iterator it = queue.begin();
            while(pos--)    it++;//找到插入位置
            queue.insert(it, people[i]);
        }
        return vector<vector<int>>(queue.begin(), queue.end());
    }
};

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

解法,贪心:局部最优:当气球出现重叠,一起射,所用弓箭最少 -》全局最优:把所有气球射爆所用弓箭最少。

day34打卡_第2张图片

class Solution {
    static bool cmp(vector<int>& a, vector<int>& b)
    {
        return a[0] < b[0];
    }
public:
    int findMinArrowShots(vector<vector<int>>& points) {
        //按照气球起始位置排序
        sort(points.begin(), points.end(), cmp);
        //计算箭的数量
        int ret = 1;//最少使用一个
        for(int i = 1; i < points.size(); i++)
        {
            //判断气球是否重叠
            //右边气球的左边界,是否大于,左边气球的右边界
            if(points[i][0] > points[i-1][1])
            {
                //大于就多用一根箭
                ret++;
            }
            else
            {
                //小于等于就使用同一根箭,
                //并且缩小气球重叠边界范围(更新为左边的气球右边界和当前气球的右边界最小值)
                points[i][1] = min(points[i][1], points[i-1][1]);
            }
        }
        return ret;
    }
};

你可能感兴趣的:(代码,算法,leetcode)