134. 加油站
- 全局思考:总油量减去总消耗大于等于零那么一定可以跑完一圈,
- 局部贪心:累加每个站的净胜油量,如果<0,则在此之前(包括该站)都不是起始位置,从下一个位置开始寻找
cpp
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int cursum = 0, totalsum = 0;
int start = 0;
for (int i = 0; i < gas.size(); i++) {
cursum += gas[i] - cost[i];//累加油量净剩量
totalsum += gas[i] - cost[i];
if (cursum < 0) {//i位置之前一定不满足
start = i + 1;//从i下一个位置开始重新寻找
cursum = 0;
}
}
if (totalsum < 0)//总油量大于消耗的,所以肯定不能跑一圈
return -1;
return start;
}
};
135. 分发糖果
两次遍历
- 从左到右,考虑右边比左边大的情况
- 从右到左,考虑左边比右边大的情况
cpp
class Solution {
public:
int candy(vector<int>& ratings) {
int ret = 0;
vector<int> Candy(ratings.size(), 1);
for (int i = 1; i < ratings.size(); i++) {
if (ratings[i - 1] < ratings[i])
Candy[i] = Candy[i - 1] + 1;
}
for (int i = ratings.size() - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1])
Candy[i] = max(Candy[i], Candy[i + 1] + 1);
}
for (int num : Candy)
ret += num;
return ret;
}
};
860. 柠檬水找零
贪心体现在如果支付20美元时,应该优先消耗10美元找零
cpp
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
int five = 0, ten = 0;
for (int b : bills) {
if (b == 5) five++;
else if (b == 10) five--, ten++;
else {
if (ten) ten--, five--;
else five -= 3;
}
if (five < 0) return false;
}
return true;
}
};
406. 根据身高重建队列
首先顾一个维度,按照身高排序,之后优先按身高高的people的k来插入,后序插入节点不会影响前面已经插入的节点
cpp
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);
vector<vector<int>> que;
for (int i = 0; i < people.size(); i++) {
int pos = people[i][1];
que.insert(que.begin() + pos, people[i]);
}
return que;
}
};