第一题:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
if (bills[0] != 5) return false;
map<int, int> cost;
for (int i = 0; i < bills.size(); i++) {
if (bills[i] == 5) cost[5]++;
else if (bills[i] == 10) {
if (cost[5] <= 0) return false;
else {
cost[5]--;
cost[10]++;
}
}
else {
if (cost[5] <= 0) return false;
if (cost[10] <= 0 && cost[5] < 3) return false;
if (cost[10] <= 0 && cost[5] > 2) {
cost[5] -= 3;
cost[20]++;
}
else {
cost[10]--;
cost[5]--;
cost[20]++;
}
}
}
return true;
}
};
学习记录:
局部最优:遇到账单20,优先消耗美元10,完成本次找零。全局最优:完成全部账单的找零。
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0, ten = 0, twenty = 0;
for (int bill : bills) {
// 情况一
if (bill == 5) five++;
// 情况二
if (bill == 10) {
if (five <= 0) return false;
ten++;
five--;
}
// 情况三
if (bill == 20) {
// 优先消耗10美元,因为5美元的找零用处更大,能多留着就多留着
if (five > 0 && ten > 0) {
five--;
ten--;
twenty++; // 其实这行代码可以删了,因为记录20已经没有意义了,不会用20来找零
} else if (five >= 3) {
five -= 3;
twenty++; // 同理,这行代码也可以删了
} else return false;
}
}
return true;
}
};
第二题:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
这道题看了题解,能明白先按身高从高到矮、按人数从少到多排列,但是sort以后的插入仍然没搞明白,为什么直接找到前面的人数然后插入到que相应的下标就行?这个点得再好好想想。
class Solution {
public:
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
auto compare = [](vector<int> a, vector<int> b){if (a[0] == b[0]) return a[1] < b[1];
else return a[0] > b[0];};
sort (people.begin(), people.end(), compare);
vector<vector<int>> que;
for (int i = 0; i < people.size(); i++) {
int position = people[i][1];
que.insert(que.begin() + position, people[i]);
}
return que;
}
};
第三题:
力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台
自己写的,只A了90%,剩下的用例提示超时:
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
int res = 1;
auto compare = [](vector<int> a, vector<int> b){
if (a[0] == b[0]) return a[1] < b[1];
else return a[0] < b[0];
};
sort(points.begin(), points.end(), compare);
int left = points[0][0], right = points[0][1];
for (int i = 0; i < points.size(); i++) {
if (points[i][0] < right && points[i][0] > left) left = points[i][0];
else if (points[i][0] > right) {
res++;
left = points[i][0];
right = points[i][1];
}
if (points[i][1] < right) right = points[i][1];
}
return res;
}
};
GPT修改的,为了最小化需要的箭的数量,最好在每组重叠的气球末尾放置箭,因此按照结束位置对气球进行排序就行:
class Solution {
public:
int findMinArrowShots(vector<vector<int>>& points) {
if (points.size() == 0) return 0;
int res = 1;
auto compare = [](const vector<int>& a, const vector<int>& b){
return a[1] < b[1]; //不需要检查起点是否相等,只需要对齐终点就行
};
sort(points.begin(), points.end(), compare);
int arrowPos = points[0][1]; //箭的位置在能射到的最远的位置,即气球的终点
for (int i = 1; i < points.size(); i++) {
if (points[i][0] > arrowPos) { //如果下一个气球的起点大于箭的位置(前一个气球的终点,那么增加一只箭并且该箭的位置仍然是目前这个气球的终点)
res++;
arrowPos = points[i][1];
}
}
return res;
}
};
代码随想录写的没有GPT改的清楚,因此不放了。