leetcode134 加油站
算法
- 引入变量curr_gas:记录当前邮箱里剩余的总油量,如果在某一个加油站curr_gas的值小于0, 意味着我们无法达到这个加油站,下一步我们把这个加油站当做新的起点,并将curr_gas重置为0,表示重新出发。
- 引入变量total_gas = sum(gas) - sum(cost),如果total_gas < 0,则直接返回-1, 因为一定不可能环形一圈。
- 初始化total_gas和curr_gas为0,并且选择0号加油站为起点
- 遍历所有的加油站
- 每一步中,total_tank += gas[i] - cost[i], curr_gas += gas[i] - cost[i]
- 如果在i + 1号加油站,curr_gas< 0,将i + 1号加油站作为新的起点,同时重置curr_gas = 0, 让油箱也清空
- 如果total_gas < 0,返回-1,否则返回starting station,
证明为一个可行解
为可行解, 现要证明到一定是可达的,因为cur_gas > 0, 意味着至一定可达,采用反证法:
到不可达,那么不可达的位置一定满足, 可以将整条回路分成三段。
为可行解,则total_gas>=0, 因此
,
一定成立,因为如果反之的话,得到的结果出发点一定在更靠前的一个加油站,而不是
所以 恒成立
又根据假设可知,不能到达,可以分成和两部分,因此
于上式矛盾,假设不成立,从出发一定能环形一圈,是一个可行解。
代码实现
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int n = gas.length;
int total_gas = 0;
int cur_gas = 0;
int res = 0;
for(int i = 0; i < n; i++){
total_gas += gas[i] - cost[i];
cur_gas += gas[i] - cost[i];
if(cur_gas < 0){
res = i + 1;
cur_gas = 0;
}
}
return total_gas < 0 ? -1 : res;
}
}