LeetCode每日一题,134. Gas Station
先看题目描述
大意就是给定两个数组 gas 和 cost,gas[i] 代表第 i 个加油站可以给车加的油,cost[i] 代表从第 i 个加油站走到第 i + 1 个加油站,需要消耗多少油,起始时车里没油,问从某个加油站开始走,每到一个加油站就加油,能否走一个循环,不能的话就返回 -1,能的话就返回起点加油站的位置
算法和思路
暴力法
第一想法就是暴力遍历,遍历每个加油站,判断从该加油站开始走能否走一个循环。因为感觉这样实在是太暴力了,我就想办法优化,看到题目说若有解时该解唯一,于是想到当 gas[i - 1] - cost[i - 1] 大于等于 0 时,加油站 i 必不可能是起点,这个通过反证法可以证明,利用这点的话就不用每个加油站都判断一遍了
一次遍历
这个是看题解才明白的,要是我自己想的话估计想不出来
假设我们此前发现,从加油站 x 出发,每经过一个加油站就加一次油,第一个无法到达的加油站是 y(不妨设 x<y)。这就说明:
第一个式子表明无法到达加油站 y,第二个式子表明可以到达 y 之前的所有加油站
现在,考虑任意一个位于 x,y 之间的加油站 z,我们现在考察从该加油站出发,能否到达加油站 y,根据上面的式子,我们得到:
这就说明:从 x,y 之间的任何一个加油站出发,都无法到达加油站 y
在发现了这一个性质后,算法就很清楚了:我们首先检查第 0 个加油站,并试图找到第一个无法到达的加油站 x;如果能找到,下一次就从加油站 x+1 开始检查。最终,我们只遍历了原数组一次
算法源码
暴力法
1 | class Solution { |
一次遍历
1 | class Solution { |
这就是一次遍历的代码,对于最后的返回值,应该是用到了一个性质:当 totalGas >= 0时,题目要求的起点加油站一定存在,但这个性质我并不知道如何证明;当toalGas < 0 时,一定无解这点倒是很好理解的