JavaScript-加油站

一、题目描述

在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。

你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从其中的一个加油站出发,开始时油箱为空。

给定两个整数数组 gas 和 cost ,如果你可以按顺序绕环路行驶一周,则返回出发时加油站的编号,否则返回 -1 。如果存在解,则 保证 它是 唯一 的。

二、解题思路

        1.由题意得:要判断汽车能否从第 i 个加油站开到第 i+1 个加油站,要计算gas [i]与cost[i]的差值。判断其是否有充足的油行驶。如果经过前面的站点油还有剩余,则需要加上剩余的油量。

        2.不妨将计算出经过每个加油站能剩余的油量,使用数组residue存放。只要求其和sum,如果sum大于等于0,说明到达这里油量是够的,如果小于0,说明油量不够到达。将题目变成求从i开始,sum一直大于等于0,返回 i 。

三、解题代码

        示例:

/**
 * @param {number[]} gas
 * @param {number[]} cost
 * @return {number}
 */
var canCompleteCircuit = function(gas, cost) {
    const residue = []
    //获取每个站的剩余油量
    for(let i = 0;i<gas.length;i++){
        residue.push(gas[i] - cost[i])
    }
    let n = residue.length
    if(n === 1){
        if(residue[0] >= 0) return 0
        return -1
    }
    let start = 0
    let end = 1
    let sum = residue[0]
    let count = 0

    //查询和一直大于等于0的开始位置
    while(count <= 2*n){
        count++
        if(sum < 0){
            sum = 0
            start = end
        }
        sum = sum+residue[end]
        end = (end+1)%n
        if(end === start && sum >=0) return start
    }       
    return -1
};

        代码解析:代码关键为如何寻找到 i ,使得从 i 开始环绕一周时sum没有小于0的情况,最坏情况是i为最后一个,在环绕一周为次数为2n。在此过程中,如果出现sum小于0的情况,说明前面油量不够,那么重新开始,给start 赋值为 end,从当前位置继续开始,向后求和, end = (end+1)%n实现循环数组的效果,如果end == start且sum >=0;说明已经环绕一周,且油量足够。此时start及就是我们寻找的 i 。

TIP: 可能会有同学问 为什么重新开始计算sum时是 start = end ,而不是 start++。这是因为,sum是时时计算的,从计算sum的开始一定是一个正数,如果后面遇到了sum<0的情况,那一定是后面出现了一个或者多个负数。那么start++无非是抛弃了第一个正数,减少了一个正数,只会整体变小,sum加到相同的地方也必然会再小于0。

换句话说:假设前面的正数,负数相加到第i的时候sum<=0,注意这里sum是第一次<=0;(因为sum是时时判断的),因为前面的开始的数一定是正数,那么说明是一定是加了一个负数,且sum是第一次小于0,所以从前面开始的任何一段都是大于0的(从加sum的第一个数),所以去掉前面任何一段都是都是不可取的。故将start == end 重新开始计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值