题目链接:https://leetcode.com/problems/gas-station/description/
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, otherwise return -1.
Note:
The solution is guaranteed to be unique.
这道题目的意思是:有一个圆形的路线,在这条路线上有N个加油站,每走一段路程需要消耗一定的油量。问从哪一个加油站开始走可以走完这一圈。
思路一(最开始的思路):遍历,从加油站i开始,如果不能走一圈(回到加油站i),则从加油站i+1开始,以此类推......直到找到可以走完一圈的起点加油站,或者,找不到。
问题:在leetCode上运行超时。
思路二:这道题其实很巧妙,可以这样想:如果从加油站i开始,不能到达加油站j(到j时,油箱中的油量为负值),则从i到j之间的任何一个加油站开始走都不能到达加油站j。
原因:反证法:i<k<j,从加油站k开始,若从加油站i到加油站k,油的余量为负,则不能从i到k,与假设不符;若油的余量为非负,说明从加油站i到加油站k,有积攒的油(最少为0),那么,因为我们不能到加油站j,说明从加油站k到加油站j的消耗大于它们之间加油站可以加的油量,所以,必然不能从加油站k到加油站j。
所以,如果从加油站i开始,不能到达加油站j,则从i到j之间的任何一个加油站开始走都不能到达加油站j,也就i到j之间的任何一个加油站开始走都不能走完一圈。因此,我们直接从j开始即可。
另外,若总油量大于总消耗,一定可以至少找到一个开始点走完这一圈(一个数学定理,不使用此定理,也可以)。
想清楚这个问题,代码就很简单了(C++):
1 class Solution { 2 public: 3 int canCompleteCircuit(vector<int>& gas, vector<int>& cost) 4 { 5 int start = 0,totalGas = 0,totalCost = 0,tank = 0; 6 for(int i=0;i<gas.size();i++) 7 { 8 totalGas += gas[i]; 9 totalCost += cost[i]; 10 tank += gas[i] - cost[i]; 11 if(tank<0) 12 { 13 tank = 0; 14 start = i+1; 15 } 16 } 17 return (totalGas>=totalCost)?start:-1; 18 } 19 };