Day35 贪心 LeetCode 860 406 452

70 阅读1分钟

860. 柠檬水找零

心得

  • 三种情况考虑好即可,AC

题解

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        int sumFive = 0;
        int sumTen = 0;
        for (int bill : bills) {
            if (bill == 5) sumFive +=1;
            if (bill == 10) {
                sumFive -= 1;
                sumTen += 1;
            }
            if (bill == 20) {
                sumFive -= 1;
                sumTen -= 1;
                if (sumTen < 0 && sumFive > 1) {
                    sumTen += 1;
                    sumFive -=2;
                }
            }
            if (sumFive < 0 || sumTen < 0 ) return false;
        }
        return true;
    }
};

406. 根据身高重建队列

心得

  • 考虑数组插入时间复杂度过高,

题解

  • 两端分别考虑,本题二维先考虑高度排好序,然后插入不影响高度排序,第二维度插入即可,但是数组插入存在双倍扩容时间复杂度过高,最好链表插入,此时需要迭代器
class Solution {
public:
    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];
    }
    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
        sort(people.begin(), people.end(), cmp);
        // vector<vector<int>> que;
        list<vector<int>> que; // 链表插入优化
        for (int i = 0; i < people.size(); i++) {
            int pos = people[i][1];
            std::list<vector<int>>::iterator it = que.begin();
            while (pos--) {
                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++;
            } else {
                points[i][1] = min(points[i-1][1], points[i][1]); // 更新右边界
            }
        }
        return result;
    }
};