class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int cursum=0;
int 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){
start=i+1;
cursum=0;
}
}
if(totalsum<0) return -1;
return start;
}
};
这道题的贪心就是如果加油和耗油和为负,则直接从下一个加油站出发,因为前面的累加都只能为负,之前每次加油和耗油和都为正,对下一个加油和耗油都是正向增益,所以前面累加只能为负,只能选取下一个节点为出发节点,如果选到最后一个节点都不满足条件,则,必定是总耗油量大于加油量,返回-1
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
for(int i=0;i<gas.size();i++){
int rest=gas[i]-cost[i];
int index=(i+1)%gas.size();
while(rest>=0&&index!=i){
rest+=gas[index]-cost[index];
index=(index+1)%gas.size();
}
if(rest>=0&&index==i) return i;
}
return -1;
}
};
这是这道题的暴力解法,for循环适合从头到尾遍历,while循环适合环形遍历,代码巧妙的一点是利用取余实现数组的闭环循环。
135. 分发糖果
class Solution {
public:
int candy(vector<int>& ratings) {
vector<int> sugar(ratings.size(),1);
for(int i=1;i<ratings.size();i++){
if(ratings[i]>ratings[i-1]) sugar[i]=sugar[i-1]+1;
}
for(int i=ratings.size()-2;i>=0;i--){
if(ratings[i]>ratings[i+1]) sugar[i]=max(sugar[i],sugar[i+1]+1);
}
int count=0;
for(int a:sugar){
count+=a;
}
return count;
}
};
先判断从左到右,rating[i]>rating[i-1]的情况,再判断从右到左,rating[i]>rating[i+1]的情况,为什么不能从左到右再来一遍,因为rating[i]>rating[i+1],从左到右不能影响下一次判断。
对于rating[i]>rating[i-1]&&rating[i]>rating[i+1]的情况,sugar[i]要选取两次判断的最大值