離家不遠

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

问题如下:

N个加油站组成一个环状头尾相接的路线,且每个下标为i的加油站总共能加gas[i]的汽油,当前加油站到下一加油站所花费的汽油为cost[i],请写出程序判断是否存在下标index使得当你从index加油站开始开车,在车的初始汽油为0的情况下按顺序走过所有其他加油站回到index加油站,如果存在输出index值,如果不存在输出-1.

解答:

大家其实很容易能想到一个O(n^2)复杂度的方法,即遍历每个加油站(数组元素),以元素i为起点,按顺序将所有元素i之后的gas和cost汇总,当循环一轮回到元素i还未出现总和<0的情况,则说明i为解,若不是则将i+1设置为新的起点,以此类推。

其实存在O(n)复杂度的方法,即遍历一次所有加油站即可。

1、显而易见gas总和减去cost总和为正数的情况下就一定存在index解,我们的方法是基于这个命题的,我们先证明该命题是否为真,该命题逆否命题为:如果不存在解(即无解),则gas和cost的总和为负。无解可以换句话表述:不存在任何一个数i,从i开始gas[i]-cost[i]为正数,所以gas和cost总和为负数。命题得证。

2、gas总和减去cost总和为负数的情况下就不存在index解。

3、总数为正,即存在解的情况下,如果元素j到元素k总和为负,则在[j,k]范围外存在解。

程序如下:

 

/**
 * @param {number[]} gas
 * @param {number[]} cost
 * @return {number}
 */
var canCompleteCircuit = function(gas, cost) {    
    var total_gas = 0;
    var current_gas = 0;
    var index = 0;
    for(var i=0;i<gas.length;i++){
        total_gas += gas[i] - cost[i];
        current_gas += gas[i] - cost[i];
        if(current_gas < 0){
            current_gas = 0;
            index = i+1;
        }
    }
    return total_gas<0?-1:index;
};

 

posted on 2020-09-24 15:59  離家不遠  阅读(158)  评论(0编辑  收藏  举报