加油站
数组 贪心题目描述
在一条环路上有 n 个加油站,第 i 个加油站有汽油 gas[i] 升。你有一辆油箱容量无限的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升。你从某一个加油站出发,开始时油箱为空。
返回出发加油站的编号,使你能够绕环路行驶一圈;如果不存在这样的出发点,则返回 -1。
要求:
- 如果存在解,则保证它是唯一的。
思路分析
朴素的做法是枚举每一个起点,然后模拟行驶一圈,时间复杂度为 O(n^2),不够高效。
更优的做法是利用贪心:
全局判断:所有站点净油量 gas[i] - cost[i] 之和,反映了能否完成整圈行驶。如果总净油量 < 0,说明任意起点都无法完成环路,直接返回 -1。
局部贪心:否则,一定存在唯一解,贪心找到起点:
- 从第 0 站开始遍历,维护一个
currentTank(当前从候选起点出发的剩余油量)。 - 每到一站,累加该站的净油量。
- 一旦
currentTank < 0,说明从当前候选起点出发,无法走到这里,起点向后移一位,同时重置currentTank。 - 遍历结束后,
gasStationIndex就是答案。
贪心正确性:当 currentTank 变负时,可以证明候选起点到当前站点之间的任何站都不可能是有效起点,因此直接跳过它们,将起点移到下一站。
算法步骤
- 初始化
gasStationIndex = 0、totalTank = 0、currentTank = 0。 - 遍历每个站点,计算净油量
netGas = gas[i] - cost[i]。 - 将
netGas同时累加到totalTank和currentTank。 - 若
currentTank < 0,将gasStationIndex移到i + 1,并重置currentTank = 0。 - 遍历结束后,若
totalTank >= 0返回gasStationIndex,否则返回-1。
示例代码
复杂度分析
- 时间复杂度:
O(n),其中n是加油站数量。只需一次线性遍历。 - 空间复杂度:
O(1)。只用到常数个额外变量。
示例演示
以 gas = [1, 2, 3, 4, 5]、cost = [3, 4, 5, 1, 2] 为例:
每个站点的净油量:
遍历过程:
遍历结束,totalTank = 0 >= 0,返回 gasStationIndex = 3。
验证:从站点 3 出发,依次经过 3 → 4 → 0 → 1 → 2,油箱始终非负,可完成环路。