• 加油站问题 Gas Station


    2019-06-01 17:09:30

    问题描述:

    问题求解:

    其实本题本质上是一个数学题。

    【定理】

    对于一个循环数组,如果这个数组整体和 SUM >= 0,那么必然可以在数组中找到这么一个元素:从这个数组元素出发,绕数组一圈,能保证累加和一直是出于非负状态。

    【证明】

    从第一个数字开始进行累加和,中间必然会有一个累加和最低的点,我们设为x。最后的sum >= 0。

    现在我们从x出发向后累加,那么必然处于非负状态,并且到了最后一个站点还会有一定的盈余,再从开始向最低点x进发也必然不会出现负数的情况。

    【Leetcode Discuss】

    If sum of all gas[i]-cost[i] is greater than or equal to 0, then there is a start position you can travel the whole circle.
    Let i be the index such that the the partial sum

    gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]

    is the smallest, then the start position should be start=i+1 ( start=0 if i=n-1). Consider any other partial sum, for example,

    gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]+gas[i+1]-cost[i+1]

    Since gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i] is the smallest, we must have

    gas[i+1]-cost[i+1]>=0

    in order for gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i]+gas[i+1]-cost[i+1] to be greater.
    The same reasoning gives that

     gas[i+1]-cost[i+1]>=0
     gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]>=0
     .......
     gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]+...+gas[n-1]-cost[n-1]>=0 

    What about for the partial sums that wraps around?

    gas[0]-cost[0]+gas[1]-cost[1]+...+gas[j]-cost[j] + gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1]
    >=
    gas[0]-cost[0]+gas[1]-cost[1]+...+gas[i]-cost[i] + gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1]
    >=0

    The last inequality is due to the assumption that the entire sum of gas[k]-cost[k] is greater than or equal to 0.
    So we have that all the partial sums

    gas[i+1]-cost[i+1]>=0,
    gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]>=0,
    gas[i+1]-cost[i+1]+gas[i+2]-cost[i+2]+...+gas[n-1]-cost[n-1]>=0,
    ...
    gas[i+1]-cost[i+1]+...+gas[n-1]-cost[n-1] + gas[0]-cost[0]+gas[1]-cost[1]+...+gas[j]-cost[j]>=0,
    ...

    Thus i+1 is the position to start.

    因此,对于本题来说,我们可以计算一下是否总的gas - cost >= 0?如果是,那么必然存在一个解,在这个前提下,只需要遍历一遍数组,如果碰到不能到达的情况,那么就从第一个不能到达的重新开始计算即可。

        public int canCompleteCircuit(int[] gas, int[] cost) {
            int n = gas.length;
            int sum = 0;
            for (int i = 0; i < n; i++) sum += gas[i] - cost[i];
            if (sum < 0) return -1;
            int start = 0;
            int tank = 0;
            for (int i = 0; i < n; i++) {
                tank += gas[i];
                if (tank < cost[i]) {
                    start = i + 1;
                    tank = 0;
                }
                else {
                    tank -= cost[i];
                }
            }
            return start;
        }
    

      

  • 相关阅读:
    【redis】--安全
    【redis】-- 数据备份和恢复
    2018.2.8 cf
    寒假零碎的东西 不定时更新补充.......
    hdu 1018
    2018寒假acm训练计划
    UVAlive 7466
    母函数
    简单数学题(水的不能在水的题了)
    随便写写的搜索
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/10960312.html
Copyright © 2020-2023  润新知