###加油站分析
####原题 城市的环形路有n个加油站,第i个加油站的油量用gas[i]来表示,你有如下的一辆车:
- 它的油缸是无限量的,初始是空的
- 它从第i个加油站到第i+1个加油站消耗油量为cost[i]
现在你可以从任意加油站开始,路过加油站可以不断的加油,问是否能够走完环形路。如果可以返回开始加油站的编号,如果不可以返回-1。注意,解决方案保证是唯一的。
####分析 这个题目其实比较简单,只要充分的理解,我相信大家都能够解决的。你的这辆车的油缸是无限量的,所以每个加油站的油都可以加到车里,但是关键是你得保证,你在第i站的时候,油缸中有的油量,可以支撑你到第i+1站,对于每一站都要如此,所以,并不是总的油量大于消耗量就可以了。要保证每一站都有足够的油可以走到下一站,到每一站,你的车的油量都大于等于0就可以了。
经过上面的分析,很显然,暴力一点,我们每个站都试一下呗,然后找到每一站的油量都大于等于0的那个走法,返回开始的加油站;没有就返回-1。这个解法是O(n^2)的时间复杂度。
我们通过观察上面的暴力方法的步骤,可以发现有很大的改进空间。当我们从第0个加油站开始,判断是否可以走完,然后从第1个加油站开始,进行判断的时候,其实中间的计算已经做过了。反过来,我们如果计算好了从第1个加油开始,到某一个站时,油量为tank,此时考虑从第0个开始时,到该加油站的油量就是gas[i]-cost[i] + tank。这时隐约觉得,解决方案的时间复杂度可以是O(n)的时间复杂度。
事实上确实可以,具体的方法如下:tank表示当前车的油缸里的油量
- 从第0个站开始,tank += gas[0] - cost[0],只要tank>=0,我们就继续到下一个加油站
- 当不满足tank>=0,顺着环路试验从前一个站开始,比如,n-1: tank += gas[n-1] - cost[n-1],如果还小于0,继续试验再前一个。
- 直到满足 tank>=0,再进行第1步,依次类推
- 当一前一后这两个相遇了,算法也就结束了,tank>=0,就成功,返回相遇的位置;否则,失败,返回-1
上面这个方法的时间复杂度是多少呢?O(n)的,很简单,我们作为一个整体来看,每一个节点都只走了一次。
【分析完毕】