LeetCode - Gas Station(加油站)
題目描述
在一條圓形路線上有 n
個加油站,其中第 i
個加油站的汽油量是 gas[i]
。你有一輛油箱無限大的汽車,它從第 i
個加油站到第 i + 1
個加油站所需要的汽油量是 cost[i]
。你必須從某個加油站出發,並且沿著順時針方向走一圈。如果可以走完整圈,返回出發的加油站的索引(從 0 開始),否則返回 -1。
範例:
1
2
3
4
5
輸入:gas = [1,2,3,4,5], cost = [3,4,5,1,2]
輸出:3
解釋:
從加油站 3 出發可以走完整圈,剩餘的汽油依次為:
4 - 1 = 3, 3 + 5 - 2 = 6, 6 + 1 - 3 = 4, 4 + 2 - 4 = 2, 2 + 3 - 5 = 0
1
2
3
輸入:gas = [2,3,4], cost = [3,4,3]
輸出:-1
解釋:不管從哪個加油站出發,都無法走完整圈。
解法思路
此問題可以轉換為尋找從哪個加油站出發,能夠在扣除每段距離的油耗後,仍然保持汽油不為負並完成整圈。為此,我們可以使用貪心算法,根據汽油的盈虧變化來確定起點。
總油量判斷:如果所有加油站的總汽油量
sum(gas)
小於總花費sum(cost)
,則無法走完整圈,直接返回-1
。逐站遍歷:如果
sum(gas) >= sum(cost)
,則一定有解。從第一站開始,依次累加每個加油站的淨油量(gas[i] - cost[i]
):- 若當前總和
tank
為負,說明無法從起點到當前加油站,則將下一站作為新的起點。 - 重新開始的原因是:如果到達某個加油站時,總和變為負數,說明從該段起始位置無法抵達這裡;因此可以從下一站開始。
- 若當前總和
範例代碼
以下是 Python 的實現:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def canCompleteCircuit(gas, cost):
total_tank = 0 # 記錄總的油量差
current_tank = 0 # 當前路段的油量差
start_station = 0 # 起始加油站索引
for i in range(len(gas)):
total_tank += gas[i] - cost[i]
current_tank += gas[i] - cost[i]
# 如果當前油量差小於 0,則無法從 start 到達 i
if current_tank < 0:
start_station = i + 1 # 將下一站設為新的起點
current_tank = 0 # 重置當前油量差
# 如果總油量差大於等於 0,則說明存在解
return start_station if total_tank >= 0 else -1
代碼解析
- 總和檢查:如果所有加油站的總油量
total_tank
大於或等於總成本,則至少有一個解。 - 循環遍歷:
- 累加每個加油站的淨油量差。
- 當
current_tank
小於 0 時,更新起始站並重置current_tank
。
- 返回結果:若
total_tank
>= 0,則返回start_station
;否則返回 -1。
時間和空間複雜度
- 時間複雜度:O(n),其中
n
是加油站的數量,我們僅需一次遍歷。 - 空間複雜度:O(1),只需使用常數空間來存儲變量。
本文章以 CC BY 4.0 授權