View on NeetCode
View on LeetCode

Problem

There are n gas stations along a circular route, where the amount of gas at the ith station is gas[i].

You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from the ith station to its next (i + 1)th station. You begin the journey with an empty tank at one of the gas stations.

Given two integer arrays gas and cost, return the starting gas station’s index if you can travel around the circuit once in the clockwise direction, otherwise return -1. If there exists a solution, it is guaranteed to be unique.

Example 1:

Input: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
Output: 3
Explanation:
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 4. Your tank = 4 - 1 + 5 = 8
Travel to station 0. Your tank = 8 - 2 + 1 = 7
Travel to station 1. Your tank = 7 - 3 + 2 = 6
Travel to station 2. Your tank = 6 - 4 + 3 = 5
Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3.
Therefore, return 3 as the starting index.

Example 2:

Input: gas = [2,3,4], cost = [3,4,3]
Output: -1
Explanation:
You can't start at station 0 or 1, as there is not enough gas to travel to the next station.
Let's start at station 2 and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
Travel to station 0. Your tank = 4 - 3 + 2 = 3
Travel to station 1. Your tank = 3 - 3 + 3 = 3
You cannot travel back to station 2, as it requires 4 unit of gas but you only have 3.
Therefore, you can't travel around the circuit once no matter where you start.

Constraints:

  • n == gas.length == cost.length
  • 1 <= n <= 10^5
  • 0 <= gas[i], cost[i] <= 10^4

Solution

Approach: Greedy (One Pass)

The key insight is that if the total gas is less than total cost, no solution exists. Otherwise, find the starting point where we never run out of gas.

Implementation

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        # If total gas < total cost, impossible
        if sum(gas) < sum(cost):
            return -1

        total_tank = 0
        current_tank = 0
        start = 0

        for i in range(len(gas)):
            total_tank += gas[i] - cost[i]
            current_tank += gas[i] - cost[i]

            # If we can't reach next station, start from next station
            if current_tank < 0:
                start = i + 1
                current_tank = 0

        return start

Approach 2: Two Variables

class Solution:
    def canCompleteCircuit(self, gas: List[int], cost: List[int]) -> int:
        n = len(gas)
        total_surplus = 0
        current_surplus = 0
        start = 0

        for i in range(n):
            total_surplus += gas[i] - cost[i]
            current_surplus += gas[i] - cost[i]

            if current_surplus < 0:
                start = i + 1
                current_surplus = 0

        return start if total_surplus >= 0 else -1

Complexity Analysis

  • Time Complexity: O(n), single pass through arrays.
  • Space Complexity: O(1), constant extra space.

Key Insights

  1. Total Gas Check: If sum(gas) < sum(cost), no solution exists - not enough fuel for complete circuit.

  2. Greedy Start Point: If we can’t reach station i+1 from any station up to i, then no station from 0 to i can be the starting point.

  3. Reset Strategy: When current tank goes negative, reset and try starting from next station.

  4. Unique Solution: Problem guarantees unique solution if one exists, so we don’t need to verify the found start point.

  5. Why Greedy Works: If we fail to complete from station i, starting from any station before i won’t help because we’d face the same deficit.

  6. Surplus/Deficit: Track net gas (gas[i] - cost[i]) rather than separate gas and cost calculations.