返回
Python 巧解 leetcode 134. Gas Station 燃油补给问题,告别超时,O(n)算法轻松过关
后端
2023-10-28 19:30:51
问题背景
有一个环形公路,沿途分布着 n 个加油站,每个加油站都有一定的燃油供应量。现在有一辆车要沿着环形公路行驶一圈,但它目前没有足够的燃油。为了完成整个旅程,这辆车需要在某些加油站补充燃油。
已知:
- 环形公路上的加油站数量 n,及每个加油站的燃油供应量 gas[i]。
- 汽车的油箱容量为 capacity,初始油量为 0。
- 汽车每次只能在加油站补充燃油,且每次补充燃油后油箱的油量不会超过 capacity。
- 汽车可以多次经过同一个加油站。
目标:
- 找到一个最优的加油站,使得汽车能够沿着环形公路行驶一圈。
暴力解法
乍一看,解决这个问题的方法很简单:从第一个加油站出发,逐个加油站地检查,看看是否能够到达下一个加油站。如果能够到达下一个加油站,则继续前进;如果无法到达,则返回第一个加油站并从下一个加油站开始检查。
这种方法被称为暴力解法。它简单易懂,但效率极低。对于 n 个加油站,暴力解法的时间复杂度为 O(n^2)。当 n 较大时,这种方法会超时。
巧妙的 O(n) 算法
为了提高效率,我们需要找到一种巧妙的算法来解决这个问题。一种方法是使用贪心算法。贪心算法是一种在每一步做出局部最优选择,希望借此得到全局最优解的算法。
在我们的问题中,我们可以使用贪心算法来选择最优的加油站。具体步骤如下:
- 计算总油量和总消耗油量。总油量是所有加油站的燃油供应量之和,总消耗油量是汽车环绕一圈所需的燃油量。
- 如果总油量小于总消耗油量,则无法完成旅程,直接返回 -1。
- 否则,从第一个加油站出发,逐个加油站地检查,看看是否能够到达下一个加油站。
- 如果能够到达下一个加油站,则继续前进;如果无法到达,则将当前加油站的燃油供应量添加到汽车油箱中,然后从下一个加油站开始检查。
- 重复步骤 3 和步骤 4,直到汽车回到第一个加油站。
- 如果汽车能够回到第一个加油站,则找到最优的加油站。
这种算法的时间复杂度为 O(n),因为我们只需要遍历一次环形公路上的加油站。
代码实现
def canCompleteCircuit(gas, cost):
"""
:type gas: List[int]
:type cost: List[int]
:rtype: int
"""
total_gas = sum(gas)
total_cost = sum(cost)
if total_gas < total_cost:
return -1
start_station = 0
current_gas = 0
for i in range(len(gas)):
current_gas += gas[i] - cost[i]
if current_gas < 0:
start_station = i + 1
current_gas = 0
return start_station
结论
在这篇文章中,我们介绍了 leetcode 134. Gas Station 这道经典算法题的 Python 解法。我们首先介绍了一种暴力的解法,然后分析其局限性,最后给出一种巧妙的 O(n) 算法,轻松过关!