Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Coding Interview Patterns  Module 27 – Greedy algorithms and proofs

Gas station problem: where the circular tour starts

Find the pump from which a circular tour never runs dry with one running-balance scan, prove why restarting is safe, and return -1 when fuel falls short.

  • Intermediate
  • 30 minutes
  • Examples run with Python 3.14.8, Pyodide 314.0.7, Node.js 24.21.0, quickjs 0.32.0, Java 25, Clang 21.0.0 and Go 1.27.1
  • By MySmartCoPilot
Free intro, Pro: 7 of 30 minutes free
Free: The problem: a van on a ring road · The brute force, and why it fails at these sizes · What to notice. With a pass: the other 13 sections and 3 interview answers, about 23 minutes.

What you will learn

  • Find the starting point of a circular tour with one running-balance scan
  • Prove why restarting after a negative balance is safe
  • Decide that no start exists exactly when the total balance is negative
  • Read the answer off the lowest point of the running balance

Before you start

What you’ll learn · Before you start

What you will learn

  • Find the starting point of a circular tour with one running-balance scan
  • Prove why restarting after a negative balance is safe
  • Decide that no start exists exactly when the total balance is negative
  • Read the answer off the lowest point of the running balance

Before you start

On this page

The gas station problem asks where to start a circular tour. Pumps stand around a loop, each gives some fuel, each leg to the next pump costs some, and the tank starts empty. A start exists exactly when the pumps give at least as much fuel in total as the legs cost. To find it, drive once from pump 0 with a running tank, and whenever the tank goes below zero, start again at the next pump: no pump since the last start could have worked. That is one pass, O(n), and the last start it chooses is the smallest pump that completes the loop.

The problem: a van on a ring road

The problem

A delivery van drives once round a ring road with n fuel pumps, numbered 0 to n − 1 in the direction of travel. At pump i it takes on gain[i] litres, and the leg from pump i to the next pump, from the last back to pump 0, uses cost[i] litres. The tank starts empty and holds any amount. Return the smallest pump from which the van can drive the whole loop without the tank going below zero, or −1 if there is none. Limits: 1 ≤ n ≤ 10⁶ and 0 ≤ gain[i], cost[i] ≤ 10⁴.

  1. gain = [3, 1, 7, 2, 5, 0], cost = [4, 3, 2, 4, 1, 3] gives 2, the only pump that works, as in the figure.
  2. gain = [1, 2, 3], cost = [2, 3, 2] gives −1: the pumps give 6 litres and the legs cost 7.
  3. gain = [2, 2, 2], cost = [2, 2, 2] gives 0: every pump works, and 0 is the smallest.
Six pumps on a ring road with the litres each gives and each leg costs; pump 2 is the only start that completes the loop.Six pumps on a ring road, clockwise−4−3−2−4−1−30+31+12+73+24+55+0outside: + litresinside: − for the legOnly pump 2 (shaded) can start the loop.

The six-pump ring of the first example

Text description of the diagram

The figure shows six pumps, numbered 0 to 5, on a circle, driven clockwise. Beside each pump is the fuel it gives, and inside the circle, on each leg, the fuel that leg costs.

  1. Pump 0 gives 3 litres; the leg to pump 1 costs 4.
  2. Pump 1 gives 1 litre; the leg to pump 2 costs 3.
  3. Pump 2 gives 7 litres; the leg to pump 3 costs 2.
  4. Pump 3 gives 2 litres; the leg to pump 4 costs 4.
  5. Pump 4 gives 5 litres; the leg to pump 5 costs 1.
  6. Pump 5 gives nothing; the leg back to pump 0 costs 3.

The pumps give 18 litres in all and the legs cost 17. Pump 2 is shaded: it is the only pump from which the van can drive the whole loop without its tank going below zero.

The brute force, and why it fails at these sizes

Try each pump as the start, smallest first, and drive until the tank goes below zero or the loop closes:

Every start in turn, with the legs driven counted Python · brute/every_start.py
# The ring road of the lesson: pump i gives gain[i] litres, and the leg from pump i to the next costs cost[i] litres.
GAIN = [3, 1, 7, 2, 5, 0]
COST = [4, 3, 2, 4, 1, 3]


def start_by_trying_each(gain, cost):
    """Tries pump 0, then 1, ...: drives the loop until the tank would go below zero. Returns (start, legs driven)."""
    n, legs = len(gain), 0
    for start in range(n):
        tank = 0
        for k in range(n):
            i = (start + k) % n
            tank += gain[i] - cost[i]
            legs += 1
            if tank < 0:  # the van runs dry on the leg out of pump i
                break
        else:
            return start, legs
    return -1, legs


print("the six-pump ring:", start_by_trying_each(GAIN, COST))
print("gain [1, 2, 3], cost [2, 3, 2]:", start_by_trying_each([1, 2, 3], [2, 3, 2]))
for n in (1_000, 2_000, 4_000):
    cost = [1] * (n - 1) + [2]  # every leg costs what its pump gives, except the last, one litre short
    print(f"{n:,} pumps, one litre short in all: {start_by_trying_each([1] * n, cost)[1]:,} legs driven")

Output

the six-pump ring: (2, 8)
gain [1, 2, 3], cost [2, 3, 2]: (-1, 5)
1,000 pumps, one litre short in all: 500,500 legs driven
2,000 pumps, one litre short in all: 2,001,000 legs driven
4,000 pumps, one litre short in all: 8,002,000 legs driven

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 every_start.py

The six-pump ring costs 8 legs before pump 2 gets round. On a ring where each pump gives exactly what its leg costs, except for one leg a litre short, every start drives all the way to that leg: 500,500 legs for 1,000 pumps, 8,002,000 for 4,000, and about 5 × 10¹¹ for a million, far more than a time limit of a second or two allows.

What to notice

  • The total decides whether any start works. If the pumps give less fuel than the legs cost, every start runs dry somewhere on the loop.
  • One failure rules out a whole stretch of starts. A van that started at pump s and runs dry on the leg out of pump j shows that every start from s to j fails too: each of them would skip a part of the drive that never left the tank below zero.

The one-pass scan, step by step Pro: opens with a Pro, Premium or Ultimate pass

In this part:

  • Why restarting after a failure is safe: the proof
  • Why a start exists whenever the total is not short: the proof
    • The scan returns the smallest good start
  • A dry run on the six-pump ring
  • Every good start, and the fuel a fixed start needs
  • The code in five languages
    • Checked against trying every start on 1,000 random rings
  • Four bugs and a 32-bit total, each with its smallest failing ring
  • Edge cases
  • Variants
  • Exercise: where the van should start
    • Where a delivery van should start its ring road
  • A practice set with sample answers
  • Check yourself
  • Interview questions
    • In the gas station scan, why may you skip every pump between the current start and the pump on whose leg the tank went below zero?
    • A route planner asks the same ring, again and again, whether a given pump is a good start, and between questions single pumps change how much fuel they give. How do you answer each question quickly, and what does each change cost?
    • The van's tank now holds at most C litres, and fuel beyond that is lost at the pump. Does the one-pass scan still find a start? Show what breaks, and give a correct method with its cost.
    • The van may now drive the loop either way round and must come back to its start. How do you find the smallest pump that works in at least one direction? Say which leg each pump pairs with when the van drives the other way.
  • Key takeaways

1 diagram · 6 runnable examples (C++, Go, Java, JavaScript, Python) · 1 exercise with sample tests · 3 interview answers · about 23 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.