860.柠檬水找零
860题目链接
情况一:账单是5,直接收下。
情况二:账单是10,消耗一个5,增加一个10
情况三:账单是20,优先消耗一个10和一个5,如果不够,再消耗三个5
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int fiveCount = 0;
int tenCount = 0;
for (int i = 0; i < bills.size(); i++) {
if (bills[i] == 5) fiveCount++;
else if (bills[i] == 10 && fiveCount >= 1) {
fiveCount--;
tenCount++;
}
else if (bills[i] == 20 && tenCount >= 1 && fiveCount >= 1) {
tenCount--;
fiveCount--;
}
else if (bills[i] == 20 && fiveCount >= 3) fiveCount -= 3;
else return false;
cout << fiveCount << endl;
}
return true;
}
};
406.根据身高重建队列
406题目链接
当做题遇到两个纬度的时候,一定不要同时考虑,如果两个纬度一起考虑,一定会顾此失彼;一定要确定一个维度,再去确定另一个维度
先确定k,按照k 排序 发现并不符合条件,
按照身高h 从大到小来排序,可以明确一个维度,就是前面结点的身高一定都比本结点高,所有下面只需要按照k 为下标 重新插入队列就可以了, 因为后面的结点没有前面的结点高,所以插入之前并不影响。
使用vector
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<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);
vector<vector<int>> queue;
for (int i = 0; i < people.size(); i++) {
queue.insert(people[i][1] + queue.begin(), people[i]);
}
return queue;
}
};
使用链表优化
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);
list<vector<int>> queue;
for (int i = 0; i < people.size(); i++) {
int position = people[i][1];
list<vector<int>>::iterator it = queue.begin();
while(position--) {
it++;
}
queue.insert(it, people[i]);
}
return vector<vector<int>>(queue.begin(), queue.end());
}
};
452. 用最少数量的箭引爆气球
452题目链接
局部最优:当气球出现重叠,一起射,所用弓箭最少。全局最优:把所有气球射爆所用弓箭最少。
如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。
首先按照 气球的x_start 进行排序,假如两个气球之间没有公共区间,一定再需要一支弓箭,如果有公共区间,一定是射在 公共区间的最右边,尽可能去覆盖后面的气球,思路进行转换,可以将具有重叠区域的气球的右边界,更新为它与上一个的最小边界,然后循环。
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];
}
int findMinArrowShots(vector<vector<int>>& points) {
if (points.size() == 0) return 0;
sort(points.begin(), points.end(), cmp);
int cout = 1;
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > points[i - 1][1]) { // 气球i 和 i - 1 不挨着,则再需要一支箭
cout++;
}
else {
points[i][1] = min(points[i][1], points[i - 1][1]); // 更新重叠气球的最小右边界
}
}
return cout;
}
};