在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
如果你可以绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1。
说明:
如果题目有解,该答案即为唯一答案。
输入数组均为非空数组,且长度相同。
输入数组中的元素均为非负数。
方法:贪心算法
首先看懂题意,就如上图所示,每个车站都有不同升油,从一个车站到下一个车站的路上又要消耗一部分油,问问从任何一个站点出发能不能环形一圈?
最简单的方法是从第一个站点算看看能不能环形一圈,再换到第二个站点看看能不能环形一圈,再第三个站点。。。时间复杂度为O(n2),感人。有没有一个好的方法,循环一遍就能判断能不能环形一圈,并且把起始站点算出来?有!还真有!
如果定义始发站start,始发站必须满足gas[start]-cost[start]>=0:
如果有整体和大于等于0(下式):
则,对任意一个start,假设:
这是肯定的,始发站之前的站点都已经验证过了,不可能作为始发站,那么:
如果我们把从start到n-1压缩为一个站,从0到start-1压缩为一个站,就两个站,一定能环绕一圈,所以,只需满足两个条件,便能确定能不能环绕一圈和始发站的位置:
(1)
(2)
程序:
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
{
int totalsum = 0;
int currentsum =0;
int start = 0;
for(int i=0;i<gas.size();i++)
{
totalsum += gas[i]-cost[i];
currentsum +=gas[i]-cost[i];
if(currentsum<0)
{
currentsum = 0;
start = i+1;
}
}
return totalsum<0?-1:start;
}
};