Gas Station Problem β Greedy Circular Tour
- If total gas β₯ total cost, exactly one valid starting station exists.
- Track cumulative surplus; when it goes negative, reset start to next station.
- O(n) time, O(1) space β single pass.
The gas station problem is LeetCode 134 and a canonical example of a greedy algorithm with a non-obvious correctness proof. The O(n) solution looks almost too simple β one pass, tracking two sums β but the proof of why it works is the important part.
The key insight, once you see it, is unforgettable: if you start at station S and fail at station K, then no station between S and K can be a valid starting point. They would all fail at K too, having less fuel at that point than S did. This single observation collapses what looks like an O(n^2) search into a single linear pass.
O(n) Greedy Solution
Key insight: if the total gas β₯ total cost, a solution always exists. To find it: track current tank. If tank goes negative, the current start is invalid β reset start to next station and reset tank.
def can_complete_circuit(gas: list[int], cost: list[int]) -> int: total_surplus = 0 current_surplus = 0 start = 0 for i in range(len(gas)): diff = gas[i] - cost[i] total_surplus += diff current_surplus += diff if current_surplus < 0: # Can't start from any station 0..i start = i + 1 current_surplus = 0 return start if total_surplus >= 0 else -1 print(can_complete_circuit([1,2,3,4,5], [3,4,5,1,2])) # 3 print(can_complete_circuit([2,3,4], [3,4,3])) # -1
-1
Why the Greedy Works
Two key observations:
- If total gas β₯ total cost, a solution exists. The sum of all surpluses is non-negative, so there must be some starting point where cumulative sum never goes negative.
- If starting from S, you run out at station k, then no station between S and k works as a start. Proof: if you could start from some S' between S and k, then starting from S (which has non-negative surplus from S to S') would also work from S' β but we know you run out at k. Contradiction. So S' is also invalid.
This means once we reset start to i+1, all previous starts are definitively ruled out.
Worked Example
gas = [1, 2, 3, 4, 5] cost = [3, 4, 5, 1, 2] diff = [-2,-2,-2, 3, 3]
i=0: surplus=-2 < 0 β start=1, surplus=0 i=1: surplus=-2 < 0 β start=2, surplus=0 i=2: surplus=-2 < 0 β start=3, surplus=0 i=3: surplus=+3 β start still 3 i=4: surplus=+3+3=6 β start still 3 total_surplus = -2-2-2+3+3 = 0 β₯ 0 β return start=3 β
Verify: start at 3 with 0 fuel. - Station 3: +4, -1 = 3 remaining. Drive to 4. - Station 4: +5, -2 = 6. Drive to 0. - Station 0: +1, -3 = 4. Drive to 1. - Station 1: +2, -4 = 2. Drive to 2. - Station 2: +3, -5 = 0. Back to start. β
π― Key Takeaways
- If total gas β₯ total cost, exactly one valid starting station exists.
- Track cumulative surplus; when it goes negative, reset start to next station.
- O(n) time, O(1) space β single pass.
- The greedy works because a failed start rules out all intermediate stations as potential starts.
- Total surplus β₯ 0 is both necessary and sufficient for a solution to exist.
Interview Questions on This Topic
- QWhy does resetting start to i+1 when surplus goes negative always give the correct answer?
- QProve that if total gas β₯ total cost, a valid starting station always exists.
- QWhat is the time and space complexity of the greedy gas station solution?
- QCan there be more than one valid starting station? Why or why not?
Frequently Asked Questions
Is there a case with exactly one valid start vs multiple valid starts?
When a solution exists, it is unique. If there were two valid starting stations, you could start from one, reach the other with positive fuel, continue the circuit, and return β implying surplus at both points, but that leads to a contradiction in the balance.
Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.