第一题: 860.柠檬水找零
这道题凭借常识基本就能解决,需要注意的点就是:当顾客付的钱是20元时,我们优先给对方10元,再给一张5元,尽可能把5元留在手上。
代码如下:
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int n = bills.size();
int money[2] = {0}; //分别代表5,10元纸币的张数
for(int i = 0; i < n; i++) {
if(bills[i] == 5) money[0]++;
else if(bills[i] == 10) { //顾客支付的是10元
money[0]--;
if(money[0] < 0) return false;
money[1]++;
}
else { //顾客支付的是20元
if(money[1] != 0) { //有10元的钞票在手
money[1]--;
money[0]--;
if(money[0] < 0) return false;
}
else { //手里没有10元钞票
money[0] -= 3;
if(money[0] < 0) return false;
}
}
}
return true;
}
};
第二题: 406.根据身高重建队列
这道题和之前那道分发糖果的题目类似,不能同时考虑两边,需要先考虑一个条件,再考虑另一个条件,不然会顾此失彼,无法得到正确结果。
思路如下:
①首先,按照身高从高到低对传入的数组进行排序,当两者身高相同时,k较小的元素排列在前;
②对于排序好的数组,从前向后插入到新的数组中,插入位置就是k的值(可以考虑使用list,因为vector的插入效率较低)。
代码如下:
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) {
sort(people.begin(), people.end(), cmp);
list<vector<int>> tmp;
for(int i = 0; i < people.size(); i++) {
int pos = people[i][1];
auto it = tmp.begin();
while(pos--) it++;
tmp.insert(it, people[i]);
}
return vector<vector<int>>(tmp.begin(), tmp.end());
}
};
第三题: 452. 用最少数量的箭引爆气球
这道题可以先对数组进行排序,将第一个下标较小的放在前 面,第一个下标较大的放在后面,这样就可以用贪心算法来做了。局部最优就是:一支箭尽可能最多的引爆气球;全局最优:用最少的箭射爆全部气球。比较规则如下:当前数组的第一个元素大于前一个数组的后面一个元素时,说明需要多加一支箭了;else更新前一个数组的后一个元素为当前数组后一个元素和前一个数组后一元素之间较小的那个。
代码如下:
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end());
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;
}
};
Day35打卡!!!