首页 > 代码库 > Leetcode:Gas Station 加油站

Leetcode:Gas Station 加油站

Gas Station

There are N gas stations along a circular route, where the amount of gas at station i is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations.

Return the starting gas station‘s index if you can travel around the circuit once, otherwise return -1.

Note:
The solution is guaranteed to be unique.

 

解题分析:

我们将每个加油站的gas[i]减去cost[i], gas[i] - cost[i]可看作此加油站的剩余附加值

首先我们是从i = 0个gas station计算起的,设开始剩油量为left=0,如果这个station的油是可以到达下一个station的,那么left=gas[i] - cost[i]为正数,

到了下一个station就有两种情况:

1 如果i=1个station的gas-cost也为正,那么前面的left加上当前station的剩油量也为正。

2 如果i=1个station的gas-cost为负,那么前面的left加上当前的station的剩油量也有两种情况:

  a: left为正,那么可以继续到下一个station,重复前面计算i=2,i=3...,直到发生 b情况

  b: left为负,那么就不能到下一个station了,这个时候如果i=k(i<k<n),这个时候是否需要从第i=1个station开始重新计算呢?

  不需要,因为第k个station之前的所有left都为正的,到了第k个station才变成负。

比如:加油站1剩余 1L,加油站2剩余 2L, 加油站3剩余 -3L, 加油站4剩余 -8L (即 gas[4] - cost[4] = -8)

这时从加油站1可以达到加油站2(因为1>=0) 然后可以达到加油站3(因为1+2>=0),然后可以达到加油站4(因为1+2-3>=0)

但是不能达到加油站5(因为1+2-3-8 <0)

此时我们需要从头从第2个加油站开始吗? 不需要,因为前4站都是可达的(累计和>=0),一直到第5站才不可达

现在如果从第2站开始,相当于把第1站的正向贡献附加值去掉了,那么到达第5站时的 累计和只会更小 (2-3-8),所以肯定不正确

我们这时应该直接从第5站开始

 

另外注意:只有当 所有站gas[i]之和 >= 所有cost[i]之和 才存在解

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        if (gas.size() <= 0 || cost.size() <= 0) return -1;
        if (gas.size() != cost.size()) return -1;
        int total = 0;
        int j = -1;
        int curSum = 0;
        for (int i = 0; i < gas.size(); ++i) {
            curSum += gas.at(i) - cost.at(i);
            total += gas.at(i) - cost.at(i);
            if (curSum < 0) {
                j = i;
                curSum = 0;
            } 
        }
        return total >= 0 ? j + 1 : -1;
    }
};

每次插值累计和小于0时,我们就从下一加油站开始重新计数

total表示 所有gas[i] - cost[i]