大概题意:有n个车站,给定两个数组gas 和 cost。对于任意车站i,gas[i]表示在车站i能够加的油的升数,cost[i]表示从车站i开向车站i + 1(车站n-1则是开向车站0)所要耗费的油的升数。问能否从某个车站出发,成功的绕所有车站一次,并回到原来的车站(需要按照车站号递增的顺序,车站n-1的下一个车站为0)。车初始是没有油的。若能,则返回起始车站号,否则返回-1。
一种简单的做法是遍历所有的起点,然后判断以该车站为起点能不能走完全程。时间复杂度为O(n2)。
但这种做法其实是过于复杂的了。有一种简单剪枝方法:如果车站i能够成功到达j - 1,但不能到达j,则i +1 ~ j-1 也不能到达j 。为什么呢?以i为起点,到达i + 1 ~ j - 1时,车的油的“存量”显然是大于等于以其中某个点为起点的存量的。既然存量多的时候都过不去,存量少的时候就更不用说了。
具体实现如下,时间复杂度为O(n),代码中的lastst用来表示上一次的起点,用来判断是不是已经“绕了一圈”了.
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int st = 0 ;
int lastst = -1 ;
int n = gas.size() ;
while (true ) {
bool ok = true ;
int nowgas = 0 ;
for (int i=0; i<n; i++) {
nowgas += gas[(st + i)%n] ;
nowgas -= cost[(st + i)%n] ;
if (nowgas < 0) {
ok = false ;
st = (st + 1 + i)%n ;
break ;
}
}
if (ok ) return st ;
if (st < lastst) break ;
lastst = st ;
}
return false ;
}
};