Problem
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.
Example
Given 4 gas stations with gas[i]=[1,1,3,1]
, and the cost[i]=[2,2,1,1]
. The starting gas station's index is 2.
Challenge
O(n) time and O(1) extra space
Note
看到这个题目,怎样可以不把它当成一个环路来分析,以及减少多余的空间呢?
例如gas[i]=[1,1,3,1]
, cost[i]=[2,2,1,1]
,我们引入单次剩余油量res,剩余油量和sum,总剩余油量和total,以及可行起点start四个参数。大体上说,只要total > 0
,一定有解。下面来找起点,当sum < 0
的时候,一定是上一个加油站的单次剩余油量res为负,且与上一次的剩余油量和sum相加依然为负,说明在上一个加油站出现了消耗大于补给的情况,因此一定不能将它作为起点。所以跳过这个耗油量很大的油站,然后将下一个油站作为起点继续判断即可。
Solution
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int start = 0, sum = 0, total = 0;
for (int i = 0; i < gas.length; i++) {
int res = gas[i] - cost[i];
//如果上一次的剩余油量之和sum’加上油站油量gas[i-1],
//依然少于上次次的消耗油量cost[i-1]
if (sum < 0) {
//更新出发地点为第i个加油站
start = i;
//更新剩余油量之和为到达第i个加油站补给后的剩余油量
sum = res;
}
//否则,将之前的剩余油量之和sum加上本次消耗及补给后的剩余油量res
else {
sum += res;
}
//累计所有油站的可补给油量和总消耗油量之差(res)
total += res;
}
return total >= 0 ? start : -1;
}
}
Optimized:
public class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int start = 0, sum = 0, total = 0;
for (int i = 0; i < gas.length; i++) {
int res = gas[i] - cost[i];
sum += res;
total += res;
if (sum < 0) {
sum = 0;
start = i + 1;
}
}
return total >= 0 ? start : -1;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。