0
点赞
收藏
分享

微信扫一扫

加油站(比较难)

玉新行者 2022-05-06 阅读 99

在这里插入图片描述

方法一

public int canCompleteCircuit(int[] gas, int[] cost) {
        // 油箱里油的最小值
       int min = Integer.MAX_VALUE;
       int sum = 0;
       for(int i = 0;i<gas.length;i++){
        //    每趟剩余的油 
           int rest = gas[i] - cost[i];
        //    油的总和
            sum += rest;
        //    油的最小差值
            min = Math.min(sum,min);
       }
        // 油的总量小于要消耗的总量,不可以行驶一周  
        if(sum < 0) return -1;
        // 油的最小差值都不为负数,说明从0开始,每趟行驶都有富余的油
        if(min >= 0) return 0;
        // 从后往前找,看哪个位置富余的油刚好把油的最小差值补上,就从哪里开始
        for(int i = gas.length-1;i>=0;i--){
           int rest = gas[i] - cost[i];
           min += rest;
           if(min>=0) return i;
       }
       return -1;

    }

该解法是从全局最优解上考虑的。
情况一:如果gas的总和小于cost总和,那么无论从哪里出发,一定是跑不了一圈的

情况二:rest[i] = gas[i]-cost[i]为一天剩下的油,i从0开始计算累加到最后一站,如果累加没有出现负数,说明从0出发,油就没有断过,那么0就是起点。

情况三:如果累加的最小值是负数,汽车就要从非0节点出发,从后向前,看哪个节点gas[i] - cost[i]能这个负数填平,能把这个负数填平的节点就是出发节点。(注意添补时是累加的,比如最小差值min=-6,最后一趟富余的油为3,那么min此时就为-3,再找哪个能填上-3。不是一次性把-6给补上)

方法二

public int canCompleteCircuit(int[] gas, int[] cost) {
        // 总剩余油量,若小于0 说明无法跑完全程
        int allSum = 0;
        // 剩余油量
        int rest = 0;
        // 开始位置
        int start = 0;

        for(int i = 0;i<gas.length;i++){
        	剩余油量的和
            rest += gas[i] - cost[i];
            总的剩余油量,不可以小于0
            allSum += gas[i] - cost[i];
            若剩余油量的和小于0,那么之前这段区间都不可以,剩余油量重置为0,起始位置从i+1开始
            if(rest<0){
                start = i+1;
                rest = 0;
            }
        }
        if(allSum < 0) return -1;
        return start;

    }

此做法为贪心思想,局部最优推出全局最优。若从0到当前i位置的剩余油量累加为负数,那么从0至i区间的所有位置都不可以,起始位置一定在i的后面。

举报

相关推荐

0 条评论