Gas Station

Leetcode问题: 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-cost都必须不能为负。于是第一个思路就是对于每个点假定为出发点,然后走一圈试试。这个方法的复杂度是O(N*N)的。后来想如何才能只遍历一遍就计算出结果。联想到另一个问题《数组的最大子序列和》,那个问题的最优解就是只遍历一遍,其中当累积的和为负数时,马上归零,重新开始累积,并且不回头。后来发现,这个方法可以解决当前问题。

注意到这个问题的一个条件:如果问题有解,那就有唯一解。什么情况下没解呢?数组总和为负的情况一定没有解;数组总和为正就一定有解吗?(这个我现在还没想明白!)

在遍历的时候记录累积和sum,如果sum为负数马上归零。这样可以保证,从sum所含的第一个位置开始到当前的位置的累积和都是非负的(满足题意的)。当sum为负数时,为什么不需要回溯呢?因为sum为负是刚刚遇到的这个数造成的,不管回溯到哪儿,遇到这个数必然还会为负。因此不需回溯,从下一个开始重新累积sum。

因为问题只有唯一解,所以一次遍历下来就能找到结果。

class Solution {
public:
    int canCompleteCircuit(vector<int> &gas, vector<int> &cost) {
        
        int i;
        vector<int> value;
        int total = 0;
        int n = gas.size();
        for(i=0;i<n;i++)
        {
            value.push_back(gas[i] - cost[i]);
            total += value[i];
        }
        
        if(total < 0)
            return -1;
        
        int sum = 0;
        int idx = 0;
        for(i=0;i<n;i++)
        {
            sum += value[i];
            if(sum < 0)
            {
                sum = 0;
                idx = i+1;
            }
        }
        return idx;
    }
};



你可能感兴趣的:(Gas Station)