Skip to main content

134.加油站

标签: greedy, array

难度: Medium

通过率: 45.77%

原题链接: https://leetcode.com/problems/gas-station/description/

题目描述

在一个环形路上有 n 个加油站,其中第 i 个加油站有 gas[i] 升汽油。你有一辆无限容量的油箱,从第 i 个加油站驶往下一个 i + 1 个加油站需要消耗 cost[i] 升汽油。你从某个加油站出发,初始时油箱为空。请问按照顺时针方向绕行一圈,能否到达出发的加油站。如果可以,返回出发的起始加油站的索引;否则,返回 -1。如果存在解,保证它是唯一的。

解题思路

要解决这个问题,我们可以使用贪心算法。这个问题的关键点在于,如果从某个加油站出发,无法继续前进,那么从这个加油站之前的任何一个加油站出发也无法环绕一圈。这是因为汽油的亏空在某个点达到了最低值,而从这里之后的点出发更有可能完成整个循环。如下是详细的步骤:

  1. 初始化三个变量:总汽油余量total_tank,当前汽油余量current_tank,起始位置starting_station
  2. 遍历每个加油站:
    • 更新总汽油余量total_tanktotal_tank += gas[i] - cost[i]
    • 更新当前汽油余量current_tankcurrent_tank += gas[i] - cost[i]
    • 如果current_tank小于零,表示从起始位置starting_station无法到达当前位置i,更新起始位置starting_station为 i + 1,并重置current_tank为0。
  3. 遍历结束后,如果total_tank大于等于零,返回起始位置starting_station,否则返回 -1。这意味着不仅局部的单次行驶是可行的,并且总体上是可以完成路径环绕的。

代码实现

def canCompleteCircuit(gas, cost):
# 初始化总汽油余量,总结算需要确定能否一圈结束
total_tank = 0
# 当前汽油余量,用来决定从哪里开始
current_tank = 0
# 起始加油站索引
starting_station = 0

for i in range(len(gas)):
total_tank += gas[i] - cost[i]
current_tank += gas[i] - cost[i]

# 如果当前汽油余量小于0,意味着无法到达这里
if current_tank < 0:
# 更新起始加油站为下一个
starting_station = i + 1
# 重置当前汽油余量
current_tank = 0

# 检查总汽油余量是否允许绕行一圈
return starting_station if total_tank >= 0 else -1

复杂度分析

时间复杂度: O(n)O(n),其中 nn 是加油站的数量。我们仅需要遍历数组一次。
空间复杂度: O(1)O(1),只使用了常数级别的额外空间。