Leetcode - 860:柠檬水找零
这道题给我的感觉就是模拟>贪心,感觉就是单纯的模拟,这里的局部最优解就是当面额为20的时候优先选择用掉10的,在考虑全部用掉5的。
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
vector<int> coins(21, 0);
for(int i = 0; i < bills.size(); i++){
coins[bills[i]]++;
if(bills[i] == 10){
if(coins[5] > 0){
coins[5]--;
}else{
return false;
}
}
if(bills[i] == 20){
if(coins[10] > 0 && coins[5] > 0){
coins[10]--;
coins[5]--;
}else if(coins[10] == 0){
if(coins[5] >= 3){
coins[5] -= 3;
}else{
return false;
}
}else{
return false;
}
}
}
return true;
}
};
Leetcode - 406:根据身高重建队列
这道题的思路是:现考虑一个变量,将身高高的移动到队列前排,当两者身高一样的时候,就比较两者的插入顺序,将插入顺序小的排在前面便于先遍历到的时候先插入,拍完序后我们就遍历队列中的元素,将每个元素插入到它对应的位置即可。
class Solution {
public:
static bool abs(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(), abs);
vector<vector<int>> que(people.size());
for(int i = 0; i < people.size(); i++){
int pos = people[i][1];
que.insert(que.begin() + pos, people[i]);
}
que.resize(people.size());
return que;
}
};
Leetcode - 452:用最少数量的箭引爆气球
这道题一只箭要射中多只气球的话,取的射中位置的数字是在着多个区间的最小有边界内取得,所以当我们遇到挨着的气球的时候我们更改右边界,是有边界等于这几个区间的最小右边界:
points[i][1] = min(points[i - 1][1], points[i][1]);
对于未挨着的气球我们就直接res++。这就是我们求解局部最优解的步骤。
如果当前遍历的气球与上一个气球挨着的话我们就更改当前气球的右边界(因为弓箭需要射穿这两只挨着的气球,射中的位置必须要保证在两个区间内,呢么这个区间的右边界一定是两区间较小的右边界),如果不挨着的话我们就将弓箭数加一。
class Solution {
public:
static bool abs(vector<int>& a, vector<int>& b){
return a[0] < b[0];
}
int findMinArrowShots(vector<vector<int>>& points) {
int res = 1;
sort(points.begin(), points.end(), abs);
for(int i = 1; i < points.size(); i++){
if(points[i - 1][1] < points[i][0]){
res++;
}else{
points[i][1] = min(points[i][1], points[i - 1][1]);
}
}
return res;
}
};