134. 加油站

125 阅读2分钟

这是我参与8月更文挑战的第28天,活动详情查看:8月更文挑战

134. 加油站

从 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 升汽油。
因此,无论怎样,你都不可能绕环路行驶一周。

解题思路

  • 从下标0开始,我们计算到达每个点的油量剩余。
  • 我们发现我们在以其他点作为起点,其实油量剩余的变化曲线是不会变化的,只是整个图像往y轴方向上下移动而已,因此我们只要计算出最低点,将最低点移到y=0上面,那么就可以保证所有点的油量剩余都是大于0

代码

class Solution {
    public int canCompleteCircuit(int[] gas, int[] cost) {

        int n=gas.length;
        int min=Integer.MAX_VALUE,minIdx=-1,sum=0;
        for(int i=0;i<n;i++){
            sum+=gas[i]-cost[i];
            if(sum<min){
                minIdx=i;
                min=sum;
            }
            
        }
        return sum<0?-1:(minIdx+1)%n;
    }
}

时间复杂度:O(N)

空间复杂度:O(1)