Skip to content

Commit aca89c2

Browse files
feat: add Gas Station problem
- Greedy algorithm implementation - Multiple approaches: Brute Force, Simulation, Two Passes - O(n) time, O(1) space complexity - Comprehensive explanations and edge cases
1 parent a4bf8c2 commit aca89c2

File tree

2 files changed

+269
-0
lines changed

2 files changed

+269
-0
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Gas Station
2+
3+
## Problem Statement
4+
5+
There are `n` gas stations along a circular route, where the amount of gas at the `ith` station is `gas[i]`.
6+
7+
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.
8+
9+
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 the solution exists, it is guaranteed to be unique.
10+
11+
## Examples
12+
13+
**Example 1:**
14+
```
15+
Input: gas = [1,2,3,4,5], cost = [3,4,5,1,2]
16+
Output: 3
17+
Explanation:
18+
Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4
19+
Travel to station 4. Your tank = 4 - 1 + 5 = 8
20+
Travel to station 0. Your tank = 8 - 2 + 1 = 7
21+
Travel to station 1. Your tank = 7 - 3 + 2 = 6
22+
Travel to station 2. Your tank = 6 - 4 + 3 = 5
23+
Travel to station 3. The cost is 5. Your tank = 5 - 5 = 0
24+
Since your tank >= 0, you can travel around the circuit once.
25+
```
26+
27+
## Approach
28+
29+
### Method 1: Greedy Algorithm (Recommended)
30+
1. Track total gas and total cost
31+
2. If total gas < total cost, return -1
32+
3. Track current tank and starting station
33+
4. If tank becomes negative, reset starting station
34+
5. Most efficient approach
35+
36+
**Time Complexity:** O(n) - Single pass
37+
**Space Complexity:** O(1) - Two variables
38+
39+
### Method 2: Brute Force
40+
1. Try each station as starting point
41+
2. Simulate the journey from each station
42+
3. Less efficient than greedy approach
43+
44+
**Time Complexity:** O(n²) - Nested loops
45+
**Space Complexity:** O(1) - Two variables
46+
47+
## Algorithm
48+
49+
```
50+
1. Initialize totalGas = 0, totalCost = 0, tank = 0, start = 0
51+
2. For i from 0 to n-1:
52+
a. totalGas += gas[i]
53+
b. totalCost += cost[i]
54+
c. tank += gas[i] - cost[i]
55+
d. If tank < 0:
56+
e. start = i + 1
57+
f. tank = 0
58+
3. Return totalGas >= totalCost ? start : -1
59+
```
60+
61+
## Key Insights
62+
63+
- **Greedy Choice**: If tank becomes negative, reset starting station
64+
- **Local Optimum**: Maximum gas at each station
65+
- **Global Optimum**: Can complete the circuit
66+
- **Space Optimization**: Use only two variables
67+
68+
## Alternative Approaches
69+
70+
1. **Brute Force**: Try each station as starting point
71+
2. **Dynamic Programming**: Use DP to track gas at each station
72+
3. **Simulation**: Simulate the journey from each station
73+
74+
## Edge Cases
75+
76+
- Empty arrays: Return -1
77+
- Single station: Return 0 if gas >= cost
78+
- All stations have negative net gas: Return -1
79+
- All stations have positive net gas: Return 0
80+
81+
## Applications
82+
83+
- Greedy algorithms
84+
- Circular array problems
85+
- Algorithm design patterns
86+
- Interview preparation
87+
- System design
88+
89+
## Optimization Opportunities
90+
91+
- **Greedy Algorithm**: Most efficient approach
92+
- **Space Optimization**: O(1) space complexity
93+
- **Single Pass**: O(n) time complexity
94+
- **No Extra Space**: Use only two variables
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
* Time Complexity: O(n) - Single pass
3+
* Space Complexity: O(1) - Two variables
4+
*/
5+
class Solution {
6+
public int canCompleteCircuit(int[] gas, int[] cost) {
7+
int totalGas = 0;
8+
int totalCost = 0;
9+
int tank = 0;
10+
int start = 0;
11+
12+
for (int i = 0; i < gas.length; i++) {
13+
totalGas += gas[i];
14+
totalCost += cost[i];
15+
tank += gas[i] - cost[i];
16+
17+
if (tank < 0) {
18+
start = i + 1;
19+
tank = 0;
20+
}
21+
}
22+
23+
return totalGas >= totalCost ? start : -1;
24+
}
25+
}
26+
27+
// Alternative approach using brute force
28+
class SolutionBruteForce {
29+
public int canCompleteCircuit(int[] gas, int[] cost) {
30+
int n = gas.length;
31+
32+
for (int start = 0; start < n; start++) {
33+
int tank = 0;
34+
boolean canComplete = true;
35+
36+
for (int i = 0; i < n; i++) {
37+
int current = (start + i) % n;
38+
tank += gas[current] - cost[current];
39+
40+
if (tank < 0) {
41+
canComplete = false;
42+
break;
43+
}
44+
}
45+
46+
if (canComplete) {
47+
return start;
48+
}
49+
}
50+
51+
return -1;
52+
}
53+
}
54+
55+
// Alternative approach using simulation
56+
class SolutionSimulation {
57+
public int canCompleteCircuit(int[] gas, int[] cost) {
58+
int n = gas.length;
59+
60+
for (int start = 0; start < n; start++) {
61+
if (gas[start] >= cost[start]) {
62+
int tank = gas[start] - cost[start];
63+
int current = (start + 1) % n;
64+
65+
while (current != start && tank >= 0) {
66+
tank += gas[current] - cost[current];
67+
current = (current + 1) % n;
68+
}
69+
70+
if (current == start && tank >= 0) {
71+
return start;
72+
}
73+
}
74+
}
75+
76+
return -1;
77+
}
78+
}
79+
80+
// Alternative approach using two passes
81+
class SolutionTwoPasses {
82+
public int canCompleteCircuit(int[] gas, int[] cost) {
83+
int n = gas.length;
84+
int totalGas = 0;
85+
int totalCost = 0;
86+
87+
for (int i = 0; i < n; i++) {
88+
totalGas += gas[i];
89+
totalCost += cost[i];
90+
}
91+
92+
if (totalGas < totalCost) {
93+
return -1;
94+
}
95+
96+
int tank = 0;
97+
int start = 0;
98+
99+
for (int i = 0; i < n; i++) {
100+
tank += gas[i] - cost[i];
101+
102+
if (tank < 0) {
103+
start = i + 1;
104+
tank = 0;
105+
}
106+
}
107+
108+
return start;
109+
}
110+
}
111+
112+
// Alternative approach using iterative
113+
class SolutionIterative {
114+
public int canCompleteCircuit(int[] gas, int[] cost) {
115+
int n = gas.length;
116+
int totalGas = 0;
117+
int totalCost = 0;
118+
int tank = 0;
119+
int start = 0;
120+
121+
for (int i = 0; i < n; i++) {
122+
totalGas += gas[i];
123+
totalCost += cost[i];
124+
tank += gas[i] - cost[i];
125+
126+
if (tank < 0) {
127+
start = i + 1;
128+
tank = 0;
129+
}
130+
}
131+
132+
return totalGas >= totalCost ? start : -1;
133+
}
134+
}
135+
136+
// Alternative approach using while loop
137+
class SolutionWhileLoop {
138+
public int canCompleteCircuit(int[] gas, int[] cost) {
139+
int n = gas.length;
140+
int totalGas = 0;
141+
int totalCost = 0;
142+
int tank = 0;
143+
int start = 0;
144+
145+
for (int i = 0; i < n; i++) {
146+
totalGas += gas[i];
147+
totalCost += cost[i];
148+
tank += gas[i] - cost[i];
149+
150+
if (tank < 0) {
151+
start = i + 1;
152+
tank = 0;
153+
}
154+
}
155+
156+
return totalGas >= totalCost ? start : -1;
157+
}
158+
}
159+
160+
// More concise version
161+
class SolutionConcise {
162+
public int canCompleteCircuit(int[] gas, int[] cost) {
163+
int totalGas = 0, totalCost = 0, tank = 0, start = 0;
164+
for (int i = 0; i < gas.length; i++) {
165+
totalGas += gas[i];
166+
totalCost += cost[i];
167+
tank += gas[i] - cost[i];
168+
if (tank < 0) {
169+
start = i + 1;
170+
tank = 0;
171+
}
172+
}
173+
return totalGas >= totalCost ? start : -1;
174+
}
175+
}

0 commit comments

Comments
 (0)