问题描述:
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 in the clockwise direction, otherwise return -1.
Note:
If there exists a solution, it is guaranteed to be unique.
Both input arrays are non-empty and have the same length.
Each element in the input arrays is a non-negative integer.
Time Limited exceed总结
再度开始刷题,遇到的这道经典的gas station,题目简明易懂,但是第一次的结果 Time Limited exceed. 看了一些discussion之后,总结如下:
- 抓住了问题的处理核心:每个station都有一个收支,分别是gas数组和cost数组,所以gas数组和cost数组对应的每个元素的差值,就是这个station的收支。如果这个station的收支大于等于0,那么这个点是可以作为开始点的
- 没有抓住问题的本质:一开始的思路被上面的问题核心给限制了,停留在不断的寻找收支大于0的点(简称为可用点)。私以为问题的解决方案是
首先对所有点的收支求和,如果总体的和为负,那么直接判断为-1
如果这个可用点能够到达下一个可用点,那么就这个可用点仍然为可用,否则不可用。并重复直到只剩下一个点,这个点就是start点
- 这种解决方案虽然能够解决问题,但是太耗费时间,不够精妙
AC方案:
- 思路:任意一个start点出发,如果start到end的收支是正数,说明你可以到达end,那么就可以将就考虑end+1这个点能不能到达;反之如果收支是负数,说明start无法到达end点,那么就考虑从start-1的能不能到达end点。一次循环,直到start和end已经考虑了整个circle
- 代码
class Solution:
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
#得到每个位置的真是cost
end = 0
start = len(gas)-1
sum = gas[start]-cost[start]
while start>end:
if sum >= 0:
sum+= gas[end]-cost[end]
end +=1
else:
start -=1
sum += gas[start]-cost[start]
return start if sum>=0 else -1
- Discussion:这是一个贪婪问题,有的思想说,如果A无法到达B,那么AB之间的任何一个点都不能到达B,就将start直接设置为B的下一个点。略有疑惑,得到指点或自己能悟到精髓
总结:
在解这题的时候,还是抓住了一点问题的方案,但是自己的解决方案有些太死板了,开始点并不是固定的,也不是在一开始就可以确定的。应该根据收支来灵活的调整开始点和结束点。多练习开拓思维。
--------------------------------- 二次编辑分割线------------------------ --------------
解题思路:
start可以看作是一个分界点,如果start存在的话,所有的gas station的收支最终一定是大于等于0的。之所以Start能够作为起点,就是因为从start开始加的话,收支和一直是正数。
class Solution:
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
#得到每个位置的真是cost
tank =0
total = 0
start =0
for i in range(len(gas)):
total +=gas[i]-cost[i] #计算整个数组的和
tank += gas[i]-cost[i]#判断到点i时候的总和还是不是负数
if tank < 0:#如果是负数,说明start之前的这一段总和为负,不满足要求,重置
start = i+1
tank = 0
return start if total >=0 else -1