There's a circular route which contains gas stations. At each station, you can fill your car with a certain amount of gas, and moving from that station to the next one consumes some fuel.
Find the index of the gas station you would need to start at, in order to complete the circuit without running out of gas. Assume your car starts with an empty tank. If it's not possible to complete the circuit, return -1. If it's possible, assume only one solution exists.
Input: gas = [2, 5, 1, 3], cost = [3, 2, 1, 4]
Output: 1
Explanation:
Start at station 1: gain 5 gas (tank = 5), costs 2 gas to go to station 2 (tank = 3).
At station 2: gain 1 gas (tank = 4), costs 1 gas to go to station 3 (tank = 3).
At station 3: gain 3 gas (tank = 6), costs 4 gas to go to station 0 (tank = 2).
At station 0: gain 2 gas (tank = 4), costs 3 gas to go to station 1 (tank = 1).
We started and finished the circuit at station 1 without running out of gas.
New to this one? Start here. Below is the core idea in everyday language, plus a real-world analogy—then the sections that follow build on it with the formal reasoning, code, and step-by-step walkthroughs.
You are driving a loop with fuel stops. Some legs earn you surplus fuel, some run you down. You can only start the trip once, with an empty tank. The question is where to begin so you never coast in on fumes and stall. The trick: if the whole loop produces enough fuel overall, one good starting point is guaranteed to exist.
Two facts crack this open. (1) If total gas < total cost, no start can work — return -1. (2) Otherwise, sweep once tracking the running tank. Whenever the tank goes negative at station i, none of the stations from the current start through i can be the answer — so jump the start to i + 1 and reset. The start you are left holding is the unique answer.
Before deciding which gas station to start with, let's first determine if it's even possible to complete the circuit with the total amount of gas available.
Total gas vs total cost
Case 1: sum(gas) < sum(cost):
The first thing to realize is if the total gas is less than the total cost, it's impossible to complete the circuit. No matter where we start, we'll run out of gas before completing the circuit. So, in this situation, we should return -1.
Case 2: sum(gas) ≥ sum(cost):
Now, let's consider the more interesting case where the total travel cost is less than or equal to the total amount of gas available.
Here's a potential hypothesis:
Since there's enough total gas to cover the total cost of travel, there must be a start point in the circuit that allows us to complete it without ever running out of gas.
It's tough to confirm this hypothesis without examining an example, so let's dive into one.
Finding a start point
Consider the following example where sum(gas) > sum(cost):
We don't necessarily need to consider the gas and cost separately. At any station i, we collect gas[i] and consume cost[i] to move to the next station. We can consider both at the same time by getting the difference between these values, which provides the net gas gained or lost at each station:
Let's start at station 0 with an empty gas tank and see how far we can go. The net gas at this station is positive (1), which means we have enough gas to reach the next station. Let's add 1 to our tank:
Note that index i refers to the current gas station, whereas start refers to the gas station we started from.
At station 1, we encounter the same situation:
At station 2, our tank falls below 0, indicating we don't have enough gas to make it to the next station:
This means we cannot start our journey at station 0. Should we go back and try station 1? The key observation here is that if we didn't have enough gas to get from station 0 to station 3, we also wouldn't have enough if we started at any other station before station 3:
This is a general rule:
If we cannot make it to station b from station a, we cannot make it to station b from any of the stations in between, either:
Let's try to understand why. If we only just ran out of gas right before reaching station b, this means our tank maintained a non-negative amount of gas until station b:
Consequently, starting anywhere else before station b will result in us missing a non-negative amount of gas from the previous stations. Therefore, starting at any of these in-between stations doesn't allow us to progress to station b.
Back to our example. Let's now try resetting our tank to 0 and restarting at station 3 (at i + 1), since we just discussed how starting at stations 0 to i doesn't work:
We continue until we reach a point where we cannot proceed to the next station:
As we can see, we ran out of gas at station 5, which means we can't start from stations 3 to 5, either. So, let's try restarting at station 6.
After resetting the tank to 0, let's continue traveling through the stations:
We've reached the end of the array. Should we go back to the start of the array to check if starting from station 6 allows us to complete the circuit? Or is reaching the end from station 6 enough to finish the circuit? Let's look into this.
Proving we have enough gas to complete the circuit after reaching the end of the array
We can determine this via a proof by contradiction. If the gas we have by the end of the array is not enough, that means no solution exists: no station at which we could start in order to complete the circuit. This implies that no matter where we start, we will hit a deficit (i.e., a point where our tank falls below 0) before completing the circuit.
Consider a segment of the circuit where we run into a deficit:
We learned earlier that we cannot start at any station between a and b (inclusive) without running into a deficit. So, we can characterize this entire segment as having less total gas than the total cost required to travel through it.
After concluding that we cannot start anywhere from stations a to b, we decide to restart at the next station after b, which represents the start of the next segment. Keep in mind that since there is no solution in this proof, every segment in the circuit will end with a deficit:
This means each of these segments has less total gas than total cost. Therefore, for there to be no starting point, sum(gas) would have to be less than sum(cost).
However, we know that sum(gas) ≥ sum(cost), confirming there must be a valid start point that allows us to complete the circuit.
Therefore, in our example, we can confirm that station 6 is the answer for the following reasons.
sum(gas) ≥ sum(cost) implies that a solution must exist.
We confirmed that starting anywhere before station 6 will result in us running into a deficit.
We didn't encounter any deficit from station 6 to the last station in the array.
So, we just need to return start, which is station 6 in our example.
This is considered a greedy solution because we assume the first station we encounter that doesn't run into a deficit by the end of our array, is the start point that allows us to complete the circuit without testing every possible station in the array as the start point. The locally optimal choices (moving forward when possible, resetting when encountering a deficit) lead to the globally optimal solution (finding the correct starting point).
from typing import List
def gas_stations(gas: List[int], cost: List[int]) -> int:
# If the total gas is less than the total cost, completing the circuit is
# impossible.
if sum(gas) < sum(cost):
return -1
start = tank = 0
for i in range(len(gas)):
tank += gas[i] - cost[i]
# If our tank has negative gas, we cannot continue through the circuit from
# the current start point, nor from any station before or including the
# current station 'i'.
if tank < 0:
# Set the next station as the new start point and reset the tank.
start, tank = i + 1, 0
return start#include <vector>
#include <numeric>
using namespace std;
int gasStations(vector<int>& gas, vector<int>& cost) {
long long totalGas = 0, totalCost = 0;
for (int i = 0; i < (int)gas.size(); i++) {
totalGas += gas[i];
totalCost += cost[i];
}
if (totalGas < totalCost) { // not enough fuel overall
return -1;
}
int start = 0;
long long tank = 0;
for (int i = 0; i < (int)gas.size(); i++) {
tank += gas[i] - cost[i];
if (tank < 0) { // can't reach station i+1 from 'start'
start = i + 1; // so none of start..i works; jump ahead
tank = 0; // begin a fresh attempt
}
}
return start;
}// These methods live inside a class, e.g. class Solution { ... }
int gasStations(int[] gas, int[] cost) {
long totalGas = 0, totalCost = 0;
for (int i = 0; i < gas.length; i++) {
totalGas += gas[i];
totalCost += cost[i];
}
if (totalGas < totalCost) { // not enough fuel overall
return -1;
}
int start = 0;
long tank = 0;
for (int i = 0; i < gas.length; i++) {
tank += gas[i] - cost[i];
if (tank < 0) { // can't reach station i+1 from 'start'
start = i + 1; // so none of start..i works; jump ahead
tank = 0; // begin a fresh attempt
}
}
return start;
}Time complexity: The time complexity of gas_stations is , where denotes the length of the input arrays. This is because we iterate through each element in the gas and cost arrays.
Space complexity: The space complexity is .
Two step-by-step walkthroughs of the algorithm below: a valid case (the expected happy path) and an invalid / edge case that exercises the tricky parts. Each step shows the program state as the code runs—the same steps apply to Python, C++ and Java.
Net = [−1, 3, 0, −1]. Total gas 11 ≥ total cost 10, so a start exists. Watch the reset at station 0.
tank = −1 < 0 → station 0 (red) fails; move start to 1, reset tank.
| i | net | tank | start |
|---|---|---|---|
| 0 | -1 | -1 → reset 0 | 0 → 1 |
| 1 | +3 | 3 | 1 |
| 2 | 0 | 3 | 1 |
| 3 | -1 | 2 | 1 → return 1 |
Start at station 1. Total gas covered total cost, so the leftover start is valid. ✓
Total gas = 3, total cost = 4. Since 3 < 4, the loop can never be completed — the very first check returns -1.
| sum(gas) | sum(cost) | result |
|---|---|---|
| 3 | 4 | 3 < 4 → return -1 |
No start can work when there is not enough total fuel. ✗
sum(gas) < sum(cost) is the one-line feasibility check; the loop then needs a single pass.
Accumulate totals in long long to avoid overflow, then the same running tank logic.
Use long for the totals and tank; everything else mirrors the Python.
Tip: Demonstrate your greedy solution with examples if proving it formally is too difficult
In some problems, such as this one, proving that a greedy solution works might be complicated, especially in an interview setting. If you and the interviewer are on the same page about this, a good compromise is to demonstrate the solution's correctness with a few diverse examples. This approach allows both you and the interviewer to have confidence in your solution in the absence of a thorough proof.