有 N 個加油站環形分布,第 i 站有汽油 gas[i],開往下一站消耗 cost[i]。車油箱無限大,起始油量為 0。求能否繞行一圈,若能返回起始站索引,否則返回 -1。保證解唯一。
總油量 ≥ 總消耗 ⇔ 存在解。若總和 sum(gas[i] - cost[i]) < 0,無論從哪裡出發都無法完成。若總和 ≥ 0,則必存在唯一起點。
進一步觀察:若從站 s 出發,在站 k 時油量變負,則 s 到 k 之間的任意站都不能作為起點(因為從 s 到該站油量非負,若從中間出發油量只會更少)。因此可以直接跳過這些站,從 k+1 繼續嘗試。
total = 0(總盈虧)、tank = 0(當前油量)、start = 0(候選起點)。diff = gas[i] - cost[i]total += diff; tank += diff;tank < 0:start = i + 1; tank = 0;total >= 0 返回 start,否則返回 -1。public int canCompleteCircuit(int[] gas, int[] cost) {
int total = 0, tank = 0, start = 0;
for (int i = 0; i < gas.length; ++i) {
int diff = gas[i] - cost[i];
total += diff;
tank += diff;
if (tank < 0) {
start = i + 1;
tank = 0;
}
}
return total >= 0 ? start : -1;
}
Gas Station 是貪心算法的經典案例:利用「區間和為負則區間內無可行起點」的性質,線性掃描即可找到唯一解。關鍵在於證明總和非負時解必存在且唯一,以及跳過策略的正確性。