LeetCode 860.柠檬水找零

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

踩坑:以为不需要考虑具体怎么找钱,一直在从整体上想解决方案。

思路:当客户支付5元我们只需要收下,当客户支付10元我们只能找零5元,当客户支付20元我们优先找零一个10元一个5元,如果不行也只能支付三个5元。可以看到所有的模式相对比较固定,所以可以直接模拟。

代码:

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)
            {
                five--;
                if(five < 0) return false;
                ten++;
            }
            else if(bills[i] == 20)
            {
                if(ten > 0 && five > 0)
                {
                    ten--;
                    five--;
                }
                else if(five > 2) five = five - 3;
                else return false;
            }
        }
        return true;
    }
};

LeetCode 406.根据身高重建队列

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

踩坑:看到了类似分发糖果那题不要两边同时考虑的提示,但是没有完全理解“两边”的含义。

思路:加深了对于有多个排序依据的题目的理解。在分发糖果那题中,分发的依据分别是左边的孩子得分和右边孩子的得分。在本题中,排序的依据分别为身高和希望前面有多少人没自己低。因此,所谓的不要不要两边同时考虑的意思其实是先确定一个条件,再确定另一个。所以,所有人应先根据身高从高到低排序(因为第二个条件在意的是前面有多少人没自己低),如果身高一样则根据第二个条件从低到高排(这样更符合题意)。这样会得到一个按身高从高到低的排序,此时根据第二个条件将后面的人插到符合的位置。因为前面的人都比后面的人高,所以后面的人插到前面的队伍里并不会影响前面的人的第二个条件。

代码:

class Solution {
public:
    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) {
        vector<vector<int>> result;
        sort(people.begin(), people.end(), cmp);
        for(int i = 0; i < people.size(); i++)
        {
            result.insert(people[i][1] + result.begin(), people[i]);
        }
        return result;
    }
};

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

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

踩坑:想到要根据x从小到大排序了,但是陷入了射箭策略的陷阱,比如[1,10],[1,2],[5,8],[5,6]这种情况应该先射爆两个还是三个,以为有更节省的策略但其实都一样。

思路:根据x从小到大排序,判断相交后更新相交区间。

代码:

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