目录
? ? ? ? 本题要判断是否能实现对每位顾客正确找零,一共有5元、10元、20元三种面值的钞票,每杯柠檬水的售价是固定的5美元。只要每次交易后对三种面值的钞票进行准确的变化统计即可判断是否能够正确找零。
? ? ? ? ?对于三种不同面值的钞票,有如下处理措施:
? ? ? ? 对于20元钞票的处理,由于返现无法使用出去,因此不需要记录num20,对于两种返现方案,利用贪心的思想优先采用第一种,因为5元钞票的使用范围更广。
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
if (bills[0] != 5) return false;
int sum = 0;
// 20美元无法用于找零,因此不用设用于计数的变量
int num_5 = 0;
int num_10 = 0;
for (int i = 0; i < bills.size(); i++){
// 利用净交易值初步判断能否找零
if (sum < bills[i] - 5) return false;
// 进一步判断
if (bills[i] == 5) num_5++;
else if (bills[i] == 10) {
num_5--;
num_10++;
}
else { // 20美元的找零方式有两种:10 + 5 和 3 * 5
if (num_10 > 0){
num_5--;
num_10--;
}
else num_5 -= 3;
}
if (num_5 < 0 || num_10 < 0) return false;
sum += 5;
}
return true;
}
};
? ? ? ? 本题与昨天分发糖果的题目有些类似,也要考虑两个维度,h和k,依旧是要先想如何确定一个维度,然后再按照另一个维度重新排列。
? ? ? ? ?首先要考虑的是先按哪个维度进行排列,如果按照个数k来排,会发现k的排列并不符合条件,身高也不符合条件,两个维度哪一个都没确定下来。如果按照身高h来排,高个子的一定排在前面。
????????此时我们可以确定一个维度了,就是身高,前面的节点一定都比本节点高!按照身高排序之后,优先按身高高的people的k来插入,后序插入节点也不会影响前面已经插入的节点,最终按照k的规则完成了队列。
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>> que;
for (int i = 0; i < people.size(); i++){
int position = people[i][1];
std::list<vector<int>>::iterator it = que.begin();
while (position--){
it++;
}
que.insert(it, people[i]);
}
return vector<vector<int>>(que.begin(), que.end());
}
};
? ? ? ? 本题的难点在于如何让判断多个气球能否同时被一箭引爆。
?????????为了让气球尽可能的重叠,需要对数组进行排序,本题采用以气球起始位置排序进行排序。如果气球重叠了,重叠气球中右边边界的最小值 之前的区间一定需要一个弓箭。
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) {
sort(points.begin(), points.end(), cmp);
int num = 1;
for (int i = 1; i < points.size(); i++){
if (points[i][0] > points[i - 1][1]) num++;
else {
points[i][1] = min(points[i - 1][1], points[i][1]);
}
}
return num;
}
};
? ? ? ? 本算法的巧妙之处在于发现重合气球后,动态更新数组右边界,再对下一个数组进行重合判断。
? ? ? ? 今天的第一题难度不大,自己直接实现,第二题复习了一下对于两个维度的问题的处理方式,以及第三题初步认识了重叠区间问题的处理方法。