在一条环路上有 n
个加油站,其中第 i
个加油站有汽油 gas[i]
升。
你有一辆油箱容量无限的的汽车,从第 i
个加油站开往第 i+1
个加油站需要消耗汽油 cost[i]
升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas
和 cost
,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1
。如果存在解,则 保证 它是 唯一 的。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2] 输出: 3 解释: 从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油 开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油 开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油 开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油 开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油 开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。 因此,3 可为起始索引。
那么总共有两种最终情况出现:
1.总共的汽油都不够花的,也就是gas总和比不上cost总和,那就说明无论怎么样都不可能完整开完一圈,自然return-1即可。
2.如果不属于上面的情况,也就是赚的总的还比不上花的,那么剩下的就只能是肯定可以跑完一圈的情况了。这个时候我们只需要确定一个合适的起点即可。我们可以从第一个加油站开始遍历一遍来确认起点:用当前加油站的gas减去cost,可以得到经过这个加油站油量的剩余,如果GasRest>0,说明可以到达下一个加油站,如此反复直到碰到一个加油站使得GasRest<0,也就是说,从第一个加油站到不了这个加油站,那么中间的加油站一样到不了。所以我们应该从到不了的加油站的下一个加油站开始作为起点重新计算是否可以作为起点。因为我们已经排除了不可能绕一圈的情况,那么既然有一段路的油不够,那剩下的油肯定是有多的,所以只需要一次遍历就可以。
class Solution {
public:
int canCompleteCircuit(std::vector<int>& gas, std::vector<int>& cost)
{
int n=gas.size();
int CurrentRest=0;
int TotalRest=0;
int StartingPoint=0;
for(int i=0;i<n;i++)
{
TotalRest+=gas[i]-cost[i];//如果所有剩余加起来都不够,说明不能跑一圈
}
if(TotalRest<0)
return -1;
//通过,也就是可以跑一圈,此时只需要寻找能跑完一圈的起点即可
CurrentRest=0;
TotalRest=0;
for(int i=0;i<n;i++)
{
CurrentRest+=gas[i]-cost[i];
if(CurrentRest<0)
{
CurrentRest=0;
StartingPoint=i+1;
}
}
return StartingPoint;
}
};