Example 1
ready- Input
gas = [ 1, 2, 3, 4, 5 ] cost = [ 3, 4, 5, 1, 2 ]- Expected
3- Why
- starting at index 3 builds enough fuel to survive the wrap
A road trip around a loop has no finish line — unless your fuel tank forces one.
There are n stations on a circular route. Station i gives you gas[i] units of fuel,
and driving from station i to the next station costs cost[i] units. You begin with an
empty tank at one station, collect its fuel, and drive in the forward direction.
Return the index of the station from which you can complete one full circuit. Return -1
if no starting station works. Whenever a working start exists, it is unique.
A few ground rules:
n - 1 is index 0.1 <= gas.length == cost.length <= 10_0000 <= gas[i], cost[i] <= 10_000Hints
Try each station as the start. Walk at most n legs, updating the tank after every
station. This reveals the exact condition that makes a candidate fail.
Suppose you start at start and first run out after station i. Could any station
between start and i have done better over the remaining part of that same stretch?
Reset the candidate after every negative running tank. Separately track total fuel minus total cost; a negative total makes every starting point impossible.
If several starts were allowed to work, could you return all of them without simulating an entire circuit from every station?
Visible cases
gas = [
1,
2,
3,
4,
5
]
cost = [
3,
4,
5,
1,
2
]3gas = [
2,
3,
4
]
cost = [
3,
4,
3
]-1gas = [
5,
1,
2,
3,
4
]
cost = [
4,
4,
1,
5,
1
]4Interview signal
One failed trip can rule out a whole block of starting stations, not just the one you tried.
Start at each station and simulate up to n legs. Stop a simulation as soon as its tank
goes negative; if one survives all n legs, return that start.
def can_complete_circuit(gas: list[int], cost: list[int]) -> int:
n = len(gas)
for start in range(n):
tank = 0
for step in range(n):
station = (start + step) % n
tank += gas[station] - cost[station]
if tank < 0:
break
else:
return start
return -1Time O(n²) — up to n starts each drive n legs. Space O(1) — the simulation
stores only its tank and indices.
Scan the stations once as if the route were laid flat. tank holds the fuel balance
since the current candidate start. If it becomes negative after station i, discard the
whole stretch and try i + 1. A separate total balance decides whether any full circuit
is possible at all.
def can_complete_circuit(gas: list[int], cost: list[int]) -> int:
total = 0
tank = 0
start = 0
for i in range(len(gas)):
balance = gas[i] - cost[i]
total += balance
tank += balance
if tank < 0:
start = i + 1
tank = 0
return start if total >= 0 else -1The exchange argument is a proof that swapping rejected choices for the greedy choice
can't remove a global optimum. Suppose start first fails at station i. Before every
intermediate station k, the tank from start was non-negative. Removing that
non-negative prefix makes the balance from k through i no larger, so k also fails
by i. Exchange every candidate in that failed block for i + 1; none of the discarded
starts could be the answer. Repeating this leaves the only globally viable candidate.
If total < 0, the route consumes more fuel than all stations provide, so no start works;
if total >= 0, the surviving candidate completes the loop and is globally optimal.
Time O(n) — each station is processed once. Space O(1) — the candidate and two balances carry the proof.
Ready to run.
3 cases are queued.
Visible testcase
Case 1
Expected
3