题:https://leetcode.com/problems/gas-station/description/
题目
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.
Example 1:
Input:
gas = [1,2,3,4,5]
cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.
Example 2:
Input:
gas = [2,3,4]
cost = [3,4,3]
Output: -1
Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.
思路
解题思路
方法一
遍历每个点,选该点作为启动,然后遍历一圈,计算总和tsum是否大于0。
对这一想法进行优化:
- 构造数据 remainder[i] = gas[i] - cost[i]
- 若 remainder[i] >= 0 and remainder[i-1] < 0 ,该点进行 圈遍历。否者跳过该点。(这是由于 若 上个点 remainder[i]>=0 那上个点一定可以作为启动,减少遍历的次数)
- 在圈遍历的过程中,若tsum<0 ,取消本次圈遍历。
- 圈遍历结束后若 tsum>=0 返回当前i。
方法二
若gas.sum() - cost.sum() > 0 ,那比存在一个圈,现在确定圈的起点就可以了。
遍历整个 列表, 若从 starti开始 到 列表结束,tsum>= 0。那么 starti 为起始点。
参考:https://www.jianshu.com/p/0d8c6190a125
code
方法一
class Solution:
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
n = len(gas)
remainder = [0] * n
for i in range(n):
remainder[i] = gas[i] - cost[i]
last_visted = float('-inf')
for i in range(n):
if remainder[(i - 1 + n) % n] < 0 and remainder[i] >= 0 or n<2:
tsum = remainder[i]
j = 1
while j < n:
tsum += remainder[(i + j) % n]
if tsum < 0:
break
j += 1
if tsum >= 0:
return i
return -1
方法二
class Solution:
def canCompleteCircuit(self, gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
n = len(gas)
total = 0
tsum = 0
starti = 0
for i in range(n):
total += gas[i] - cost[i]
if tsum<0:
tsum = gas[i] - cost[i]
starti = i
else:
tsum += gas[i] - cost[i]
return -1 if total < 0 else starti