There are N
gas stations along a circular route, where the amount of gas at station i
is gas[i]
.
You have a car with an unlimited gas tank and it costs cost[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 in the clockwise direction, otherwise return -1
.
Note:
If there exists a solution, it is guaranteed to be unique.
Both input arrays are non-empty and have the same length.
Each element in the input arrays is a non-negative integer.
Example 1:
Input:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.
Example 2:
Input:
gas = [2,3,4]
cost = [3,4,3]
Output: -1
Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.
根据要求, 依次以每一个 station
作为起点, 模拟整个过程。
优化: 比如,A,B,C,D,E,F,G
几个站, 以 B
站为起点, travel 到 F
站时, 汽油不够。 那么我们就可以确定分别以 B
, C
, D
, E
几个站为起点,都到达不了 F
站。 因为既然 B
站能到达 C
, D
, E
几个站, 那么到达的时候,汽油量一定是大于等于 0
的。这时候再从 C
, D
, E
出发,汽油量实际上大于等于直接从这几个站出发的汽油量。因此,既然从 B
站到不了 F
站出发, 那从 C
, D
, E
出发也到不了 F
站。因此,我们可以直接跳过 C
, D
, E
这几个站,而直接以 F
站为起点,模拟计算。
class Solution
{
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
{
int startStation = -1; // 环绕一周的起点
int curStation; // 正在 travel 的 station
int gasTank; // gas tank 剩余的 gas
// 遍历每一个 station 作为起点
for(size_t i = 0; i < gas.size(); ++i)
{
// 初始化: gas tank 剩余 gas 为 0, 当前 station 为出发站 i
gasTank = 0;
curStation = i;
do
{
// 加气
gasTank += gas[curStation];
// 前往下一站
gasTank -= cost[curStation];
curStation = (curStation+1) % gas.size();
// 前往下一站的 gas 不够, 选择下一个 station 作为起点
if(gasTank < 0)
{
break;
}
}while(curStation != i);
// 如果 curStation 就是起点, 并且 gas tank 剩余的 gas 不为负,表示已成功绕行一周
if(curStation == i && gasTank >= 0)
{
startStation = i;
break;
}
}
return startStation;
}
};
class Solution
{
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
{
int startStation = -1; // 环绕一周的起点
int travelStation; // 当前已 travel 的 station 数
int curStation; //当前 travel 的 station
int gasTank; // gas tank 剩余的 gas
// 遍历每一个 station 作为起点(直接跳过模拟失败所经历的 station)
for(size_t i = 0; i < gas.size(); i += travelStation)
{
// 初始化: gas tank 剩余 gas 为 0, 当前 station 为出发站 i
gasTank = 0;
travelStation = 0;
curStation = i;
do
{
// 加气
gasTank += gas[(curStation)];
// 前往下一站
gasTank -= cost[curStation];
curStation = (curStation+1) % gas.size();
++travelStation;
// 前往下一站的 gas 不够, 选择下一个 station 作为起点
if(gasTank < 0)
{
break;
}
}while(curStation != i);
// 如果 curStation 就是起点, 并且 gas tank 剩余的 gas 不为负,表示已成功绕行一周
if(curStation == i && gasTank >= 0)
{
startStation = i;
break;
}
}
return startStation;
}
};