代码随想录算法训练营第三十五天 | 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球
860. 柠檬水找零
题目
解法
- 初始想法: 有点繁杂
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int set[3] = {0};
for (int i = 0; i < bills.size(); i++) {
// 收钱
if(bills[i] == 5) {
set[0] += 1;
}else if (bills[i] == 10) {
set[1] += 1;
}else {
set[2] += 1;
}
// 找钱
if(bills[i] == 10) {
set[0] -= 1;
if(set[0] < 0) return false;
}else if (bills[i] == 20) {
if(set[1] < 1 && set[0] < 3) return false;
if(set[1] >= 1 && set[0] < 1) return false;
if (set[1] >= 1) {
set[1] -= 1;
set[0] -= 1;
}else {
set[0] -= 3;
}
}
}
return true;
}
};
2.看完题解后
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int set[3] = {0};
for (int i = 0; i < bills.size(); i++) {
// 收钱
if(bills[i] == 5) {
set[0] += 1;
}else if (bills[i] == 10) {
if(set[0] < 0) return false;
set[0] -= 1;
set[1] += 1;
}else {
if(set[1] > 0 && set[0] > 0) {
set[1] -= 1;
set[0] -= 1;
}else if (set[0] >= 3) {
set[0] -= 3;
}else return false;
set[2] += 1; // 可删
}
}
return true;
}
};
406. 根据身高重建队列
题目
解法
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);
//按照前面有几个进行插入
vector<vector<int>> result;
for (int i = 0; i < people.size(); i++) {
result.insert(result.begin() + people[i][1], people[i]);
}
return result;
}
};
2.使用链表
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>> result;
for (int i = 0; i < people.size(); i++) {
int position = people[i][1];
std::list<vector<int>>::iterator it = result.begin();
while(position--) it++;
result.insert(it, people[i]);
}
return vector<vector<int>>(result.begin(), result.end());
}
};
452. 用最少数量的箭引爆气球
题目
解法
- 初始解法:只考虑了区间包含,没考虑区间包含内的区间是否相互包含
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];
}
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end(), cmp);
int result = 1;
vector<int> cur = points[0];
for (int i = 0; i < points.size(); i++) {
if(points[i][0] <= cur[1]) continue;
result += 1;
cur = points[i];
}
return result;
}
};
2.看了题解之后:使用更新最小右边界来解决区间之间相互包含
class Solution {
public:
static bool cmp(vector<int> a, vector<int> b){
return a[0] < b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
sort(points.begin(), points.end(), cmp);
int result = 1;
vector<int> cur = points[0];
for (int i = 1; i < points.size(); i++) {
if(points[i][0] > points[i-1][1]) {
result += 1;
} else { // 更新最小右边界
points[i][1] = min(points[i][1], points[i-1][1]);
}
}
return result;
}
};
感悟
贪心需要考虑的稍微全面一些,要不容易忽略一些细节