在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。
你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。
给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。
示例 1:
输入: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
输出: 3
解释: 从 3 号加油站(索引为 3 处)出发,可获得 4 升汽油。此时油箱有 = 0 + 4 = 4 升汽油
开往 4 号加油站,此时油箱有 4 - 1 + 5 = 8 升汽油
开往 0 号加油站,此时油箱有 8 - 2 + 1 = 7 升汽油
开往 1 号加油站,此时油箱有 7 - 3 + 2 = 6 升汽油
开往 2 号加油站,此时油箱有 6 - 4 + 3 = 5 升汽油
开往 3 号加油站,你需要消耗 5 升汽油,正好足够你返回到 3 号加油站。
因此,3 可为起始索引。
示例 2:
输入: gas = [2,3,4], cost = [3,4,3]
输出: -1
解释: 你不能从 0 号或 1 号加油站出发,因为没有足够的汽油可以让你行驶到下一个加油站。
我们从 2 号加油站出发,可以获得 4 升汽油。 此时油箱有 = 0 + 4 = 4 升汽油
开往 0 号加油站,此时油箱有 4 - 3 + 2 = 3 升汽油
开往 1 号加油站,此时油箱有 3 - 3 + 3 = 3 升汽油
你无法返回 2 号加油站,因为返程需要消耗 4 升汽油,但是你的油箱只有 3 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。
提示:
gas.length == ncost.length == n1 <= n <= 1050 <= gas[i], cost[i] <= 104
题解:
/**
* @description: 一次遍历 TC:O(n) SC:O(1)
* @author: JunLiangWang
* @param {*} gas 给定整数数组,表示走到该点能加的油
* @param {*} cost 给定整数数组,表示走到该点需要耗费的油
* @return {*}
*/
function onceIteration(gas, cost){
/**
* 本方案采用一次遍历的方式,首先我们如何判断能否按顺序绕环路
* 行驶一周呢?其实当gas的总和大于等于cost的总和我们肯定是能
* 够按顺序绕环路一周的,即:Sum(gas)>=Sum(cost)
*
* 如果可以按顺序绕环路行驶一周那么我们如何确定起点呢?
* 其实也很简单,我们假定起点为0,并定义一个变量diff记
* 录走过的节点gas与cost的差值的和,如果diff小于0,证明
* 该节点以及之前的节点都无法作为起点,此时将起点更新为下
* 一个节点,直至遍历结束。
*
*/
// 总加油数
let allGas=0,
// 总耗油数
allCost=0,
// 走过的节点gas与cost的差值的和
diff=0,
// 起点初始为0
index=0;
for(let i=0;i<gas.length;i++){
// 求总加油数
allGas+=gas[i]
// 求总耗油数
allCost+=cost[i]
// 记录走过的节点gas与cost的差值的和
diff+=gas[i]-cost[i];
// 如果diff小于0,证明该节点以及之前的
// 节点都无法作为起点,此时将起点更新为
// 下一个节点
if(diff<0){
diff=0;
index=i+1==gas.length?0:i+1
}
}
// 总加油数大于总耗油数,证明肯定是能
// 够按顺序绕环路一周,此时返回计算的
// 节点
if(allGas>=allCost)return index
// 否则不能返回-1
else return -1;
}