class Solution:
def canCompleteCircuit(self, gas, cost):
total_tank = 0
curr_tank = 0
start_station = 0
for i in range(len(gas)):
total_tank += gas[i] - cost[i]
curr_tank += gas[i] - cost[i]
if curr_tank < 0:
start_station = i + 1
curr_tank = 0
return start_station if total_tank >= 0 else -1
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int total_tank = 0, curr_tank = 0, start_station = 0;
for (int i = 0; i < gas.size(); ++i) {
total_tank += gas[i] - cost[i];
curr_tank += gas[i] - cost[i];
if (curr_tank < 0) {
start_station = i + 1;
curr_tank = 0;
}
}
return total_tank >= 0 ? start_station : -1;
}
};
class Solution {
public int canCompleteCircuit(int[] gas, int[] cost) {
int totalTank = 0, currTank = 0, startStation = 0;
for (int i = 0; i < gas.length; ++i) {
totalTank += gas[i] - cost[i];
currTank += gas[i] - cost[i];
if (currTank < 0) {
startStation = i + 1;
currTank = 0;
}
}
return totalTank >= 0 ? startStation : -1;
}
}
var canCompleteCircuit = function(gas, cost) {
let totalTank = 0, currTank = 0, startStation = 0;
for (let i = 0; i < gas.length; ++i) {
totalTank += gas[i] - cost[i];
currTank += gas[i] - cost[i];
if (currTank < 0) {
startStation = i + 1;
currTank = 0;
}
}
return totalTank >= 0 ? startStation : -1;
};
You are given two integer arrays, gas
and cost
, each of length n
. The i
-th gas station has gas[i]
units of gas available. It costs cost[i]
units of gas to travel from station i
to station i+1
(the last station connects to the first, forming a circle).
Your task is to determine the starting gas station index from which you can travel around the circuit once in the clockwise direction, visiting every station exactly once and returning to the starting point, without ever running out of gas. If it is not possible, return -1
.
At first glance, it might seem that we need to try starting at every station and simulate the trip, which would be a brute-force approach. For each starting index, we would check if we can make a full circle without running out of gas. However, this would be slow for large inputs.
On closer inspection, we realize that the problem is really about whether, at any point, the total gas collected so far is enough to cover the cost to the next station. If the total amount of gas is less than the total cost, it is impossible to complete the circuit from any station.
The challenge is to find the correct starting station efficiently. If we ever run out of gas at a certain station, it means that none of the stations between our previous starting point and this station can be the answer, so we can skip them.
total_tank
(to track the overall gas surplus/deficit), curr_tank
(to track the gas balance since the last starting point), and start_station
(to record the current candidate starting station).i
, add gas[i] - cost[i]
to both total_tank
and curr_tank
.curr_tank
becomes negative, it means we can't reach station i+1
from our current start_station
. Therefore, we set start_station
to i+1
and reset curr_tank
to zero.total_tank
is negative, it means the total gas is less than the total cost, so return -1
.start_station
as the answer.This approach is efficient because it only needs one pass through the arrays and skips unnecessary checks by leveraging the fact that if you can't reach a station from a certain segment, none of the stations in that segment can be a valid start.
Let's take gas = [1,2,3,4,5]
and cost = [3,4,5,1,2]
.
start_station = 1
, curr_tank = 0
start_station = 2
, curr_tank = 0
start_station = 3
, curr_tank = 0
total_tank = (1-3)+(2-4)+(3-5)+(4-1)+(5-2) = -2-2-2+3+3 = 0
total_tank >= 0
, the answer is start_station = 3
.Thus, starting at station 3 allows you to complete the circuit.
n
stations, you may have to go through up to n
stations.The Gas Station problem can be solved efficiently by realizing that if you can't reach a certain station from your current start, none of the stations in between can be valid starting points. By keeping track of the total gas surplus or deficit and resetting the starting point whenever you run out of gas, you find the unique solution in linear time. This approach is both elegant and efficient, leveraging problem constraints and cumulative logic to avoid unnecessary work.