题目
There are N gas stations along a circular route, where the amount of gas at station i isgas[i].
You have a car with an unlimited gas tank and it costscost[i]of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.
Return the starting gas station’s index if you can travel around the circuit once, otherwise return -1.
Note:
The solution is guaranteed to be unique.
现在有N个加油站围成一个圈,每个加油站可以加gas[i]的油,但是这个加油站到达下一个i+1的加油站也会花费cost[i]的油,
现在有一辆没有油的car准备从其中一个加油站出发,问是否有唯一一个加油站可以顺利走完一圈再回到起点。如果有请返回对应的加油站的index,如果没有则返回-1;
Note:很重要
这个解决方案只有一个,是唯一的。
解题思路
这里是一个典型的贪心算法,
1、如题,我们发现这其实是个一个园,则我们可以发现,如果一个加油站的gas[i]-cost[i],则对应的油是由结余的,则这时候应该继续往下走,继续累加gas[i+1]-cost[i+1]。
2、但是如果到某个加油站,却发现当前的汽油结余已经是一个负数的时候,这说明此时从这个start出发已经不是一个最合适的结果了,因为从这个start出发到当前的end的汽油结余是负值,还不如再直接从当前的end出发,由于解决方案是唯一的,这说明从当前的start出发,一定不是我们希望得到的,因为还存在一个比他更好的方案。
3、这时候,有个很巧妙的方法,即可以重新开始,又可以保留我们之前做的计算,那就是将start往后推一格(这里的所谓的往后,指的是和去end相反的方向);
则此时即相当于重新开始选取了start加油站,又可以保留我们之前的计算;
4、再次循环执行1-3,最后如果在start和end再次相遇后,发现 汽油剩余值还是>=0的则说明的确存在这样一个解决方案,可以绕一个圈再回来,而且起始点就是这个start,反之直接返回-1。
C/C++实现代码
class Solution {
public:
int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
//开始计算,然后如果遇到为负数的,就直接将start往后退一格,再进行计算,观察是否为正数;
int start = gas.size()-1;
int end =0;
int gam = gas[start] - cost[start];
while(start>end){
if(gam>0){
gam +=gas[end]-cost[end];
end++;
}else{
start--;
gam +=gas[start]-cost[start];
}
}
return gam>=0?start:-1;
}
};