2739. Total Distance Traveled
Problem Description
You have a truck with two fuel tanks - a main tank and an additional tank. The main tank initially contains mainTank
liters of fuel, and the additional tank contains additionalTank
liters of fuel.
The truck's fuel efficiency is 10 kilometers per liter. This means each liter of fuel allows the truck to travel 10 km.
There's a special refueling mechanism: For every 5 liters consumed from the main tank, if the additional tank has at least 1 liter of fuel available, exactly 1 liter will automatically transfer from the additional tank to the main tank. This transfer happens immediately after the 5th liter is consumed.
Your task is to calculate the maximum distance the truck can travel using both fuel tanks.
Key points to remember:
- The truck only runs on fuel from the main tank
- The additional tank serves as a backup that automatically refills the main tank under specific conditions
- The transfer from additional to main tank happens every 5 liters consumed (at the 5th, 10th, 15th liter, etc.)
- Each transfer moves exactly 1 liter (if available in the additional tank)
- The transfer is instant and automatic, not gradual
For example, if mainTank = 9
and additionalTank = 2
:
- After consuming 5 liters (traveling 50 km), 1 liter transfers from additional to main
- The main tank now has 5 liters (4 remaining + 1 transferred)
- After consuming another 5 liters (traveling another 50 km), 1 more liter transfers
- The main tank now has 1 liter, and the additional tank is empty
- The truck travels 10 more km with the last liter
- Total distance: 110 km
Intuition
The key insight is that we need to track when the main tank has consumed exactly 5 liters to trigger the automatic refueling from the additional tank. This suggests a simulation approach where we process the fuel consumption liter by liter.
Think of it like a counter that resets every 5 liters. Each time we use 1 liter from the main tank, we increment our counter. When the counter reaches 5 (meaning we've consumed 5 liters), we check if we can transfer fuel from the additional tank.
Why simulation works well here:
- The transfer rule is based on consumption patterns (every 5 liters), not on the current amount in the main tank
- Transfers happen at specific intervals that we need to track precisely
- Each transfer can potentially extend our journey, creating a chain reaction where the transferred liter might itself be part of another group of 5 liters
The challenge is that transferred fuel can also count toward future 5-liter consumption blocks. For example, if we consume 5 liters and get 1 liter transferred, that new liter becomes part of the next consumption cycle. This means we can't simply calculate the answer with a formula - we need to simulate the actual process.
By using a counter variable (cur
) that tracks liters consumed and checking cur % 5 == 0
, we can identify exactly when to attempt a transfer. Each iteration represents consuming 1 liter (traveling 10 km), and we continue until the main tank is empty. This straightforward simulation ensures we account for all possible transfers and their cascading effects.
Learn more about Math patterns.
Solution Approach
We implement a simulation that processes fuel consumption liter by liter. The algorithm tracks three key variables:
mainTank
: current fuel in the main tankadditionalTank
: current fuel in the additional tankcur
: counter to track consumption for the 5-liter transfer ruleans
: total distance traveled
The simulation follows these steps:
-
Initialize variables: Set
ans = 0
(total distance) andcur = 0
(consumption counter). -
Main loop: Continue while
mainTank > 0
:- Increment
cur
by 1 (we're about to consume 1 liter) - Add 10 to
ans
(each liter gives us 10 km) - Decrease
mainTank
by 1 (consume the liter)
- Increment
-
Check for transfer: After consuming each liter:
- If
cur % 5 == 0
(we've consumed a multiple of 5 liters) ANDadditionalTank > 0
:- Transfer 1 liter: decrease
additionalTank
by 1 and increasemainTank
by 1 - This transferred liter becomes available for future consumption
- Transfer 1 liter: decrease
- If
-
Return result: When the main tank is empty, return
ans
.
The beauty of this approach is its simplicity - by processing one liter at a time, we naturally handle the transfer rule without complex calculations. The modulo operation (cur % 5
) elegantly identifies when we've hit a 5-liter milestone.
For example, with mainTank = 9
and additionalTank = 2
:
- Liters 1-5: consume normally, then transfer 1 liter (mainTank becomes 5)
- Liters 6-10: consume normally, then transfer 1 liter (mainTank becomes 1)
- Liter 11: consume the last liter
- Total: 11 liters consumed × 10 km/liter = 110 km
The time complexity is O(mainTank + additionalTank)
since in the worst case, all additional fuel gets transferred. The space complexity is O(1)
as we only use a constant amount of extra variables.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a small example with mainTank = 7
and additionalTank = 1
.
Initial State:
- Main tank: 7 liters
- Additional tank: 1 liter
- Distance traveled: 0 km
- Consumption counter: 0
Simulation Process:
Iterations 1-5 (consuming first 5 liters):
- Each iteration: increment counter, travel 10 km, consume 1 liter from main
- After iter 1: main=6, additional=1, distance=10, counter=1
- After iter 2: main=5, additional=1, distance=20, counter=2
- After iter 3: main=4, additional=1, distance=30, counter=3
- After iter 4: main=3, additional=1, distance=40, counter=4
- After iter 5: main=2, additional=1, distance=50, counter=5
- Transfer triggered! (counter % 5 == 0 and additional > 0)
- Transfer 1 liter: main=3, additional=0
Iterations 6-8 (consuming remaining fuel):
- After iter 6: main=2, additional=0, distance=60, counter=6
- After iter 7: main=1, additional=0, distance=70, counter=7
- After iter 8: main=0, additional=0, distance=80, counter=8
Result: Maximum distance = 80 km
The key insight: We consumed 7 liters initially, but the automatic transfer after the 5th liter gave us 1 extra liter, allowing us to travel a total of 8 × 10 = 80 km. The transfer happened exactly when our counter hit 5, demonstrating how the modulo check (counter % 5 == 0
) captures the transfer timing perfectly.
Solution Implementation
1class Solution:
2 def distanceTraveled(self, mainTank: int, additionalTank: int) -> int:
3 # Initialize total distance and liters consumed counter
4 total_distance = 0
5 liters_consumed = 0
6
7 # Continue while there's fuel in the main tank
8 while mainTank > 0:
9 # Consume 1 liter from main tank
10 liters_consumed += 1
11 mainTank -= 1
12
13 # Each liter allows traveling 10 km
14 total_distance += 10
15
16 # Every 5 liters consumed, transfer 1 liter from additional tank to main tank
17 if liters_consumed % 5 == 0 and additionalTank > 0:
18 additionalTank -= 1
19 mainTank += 1
20
21 return total_distance
22
1class Solution {
2 public int distanceTraveled(int mainTank, int additionalTank) {
3 // Initialize total distance traveled and counter for fuel consumption
4 int totalDistance = 0;
5 int fuelConsumed = 0;
6
7 // Continue traveling while there's fuel in the main tank
8 while (mainTank > 0) {
9 // Increment the fuel consumption counter
10 fuelConsumed++;
11
12 // Each liter of fuel allows traveling 10 km
13 totalDistance += 10;
14
15 // Consume 1 liter from the main tank
16 mainTank--;
17
18 // After every 5 liters consumed, transfer 1 liter from additional tank if available
19 if (fuelConsumed % 5 == 0 && additionalTank > 0) {
20 additionalTank--; // Remove 1 liter from additional tank
21 mainTank++; // Add 1 liter to main tank
22 }
23 }
24
25 return totalDistance;
26 }
27}
28
1class Solution {
2public:
3 int distanceTraveled(int mainTank, int additionalTank) {
4 // Initialize total distance traveled and counter for fuel consumption
5 int totalDistance = 0;
6 int fuelConsumed = 0;
7
8 // Continue traveling while there's fuel in the main tank
9 while (mainTank > 0) {
10 // Consume 1 liter from main tank and travel 10 km
11 fuelConsumed++;
12 totalDistance += 10;
13 mainTank--;
14
15 // Every 5 liters consumed, transfer 1 liter from additional tank to main tank
16 // if additional tank has fuel available
17 if (fuelConsumed % 5 == 0 && additionalTank > 0) {
18 additionalTank--;
19 mainTank++;
20 }
21 }
22
23 return totalDistance;
24 }
25};
26
1/**
2 * Calculates the total distance traveled given main tank and additional tank fuel
3 * @param mainTank - The initial fuel in the main tank (in liters)
4 * @param additionalTank - The initial fuel in the additional tank (in liters)
5 * @returns The total distance traveled (in km)
6 */
7const distanceTraveled = function (mainTank: number, additionalTank: number): number {
8 // Total distance traveled in km
9 let totalDistance: number = 0;
10
11 // Counter to track every 5 liters consumed
12 let litersConsumed: number = 0;
13
14 // Continue traveling while there's fuel in the main tank
15 while (mainTank > 0) {
16 // Increment the consumption counter
17 litersConsumed++;
18
19 // Each liter of fuel allows 10 km of travel
20 totalDistance += 10;
21
22 // Consume 1 liter from main tank
23 mainTank--;
24
25 // Every 5 liters consumed, transfer 1 liter from additional tank to main tank if available
26 if (litersConsumed % 5 === 0 && additionalTank > 0) {
27 additionalTank--;
28 mainTank++;
29 }
30 }
31
32 return totalDistance;
33};
34
Time and Space Complexity
The time complexity is O(mainTank + additionalTank)
. The while loop continues as long as there is fuel in the main tank. In each iteration, we consume 1 liter from the main tank. Every 5 liters consumed, if the additional tank has fuel, we transfer 1 liter from the additional tank to the main tank. In the worst case, we consume all mainTank
liters plus transfer all additionalTank
liters (though each additional liter transferred will also be consumed). Since we can transfer at most min(additionalTank, mainTank // 5)
liters from the additional tank, and each transferred liter adds one more iteration, the total iterations is bounded by mainTank + min(additionalTank, mainTank // 5)
, which simplifies to O(mainTank + additionalTank)
or O(n + m)
where n
is the initial mainTank value and m
is the initial additionalTank value.
The space complexity is O(1)
as we only use a constant amount of extra space for the variables ans
and cur
, regardless of the input size.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
Pitfall 1: Incorrect Transfer Timing
A common mistake is transferring fuel before consuming the 5th liter instead of after. This leads to incorrect results because the transfer should happen as a response to consumption, not in anticipation of it.
Incorrect approach:
while mainTank > 0: # Wrong: checking before consumption if liters_consumed % 5 == 0 and liters_consumed > 0 and additionalTank > 0: additionalTank -= 1 mainTank += 1 liters_consumed += 1 mainTank -= 1 total_distance += 10
Correct approach:
while mainTank > 0: liters_consumed += 1 mainTank -= 1 total_distance += 10 # Correct: checking after consumption if liters_consumed % 5 == 0 and additionalTank > 0: additionalTank -= 1 mainTank += 1
Pitfall 2: Attempting Mathematical Formula Without Considering Edge Cases
Some might try to calculate the result directly using division and multiplication, but this approach often misses the nuanced interaction between consumption and refueling.
Problematic approach:
# This doesn't correctly handle the cascading effect of transfers
transfers = min(mainTank // 5, additionalTank)
total_fuel = mainTank + transfers
return total_fuel * 10
This fails because each transfer can enable additional transfers. For example, with mainTank = 9
and additionalTank = 2
, the formula gives 10 liters total, but the correct answer is 11 liters due to the cascading effect.
Pitfall 3: Off-by-One Errors in Counter Logic
Using the wrong starting value for the counter or incorrect modulo logic can cause transfers to happen at the wrong times.
Incorrect initialization:
liters_consumed = 1 # Wrong: should start at 0
Incorrect modulo check:
if (liters_consumed - 1) % 5 == 0: # Wrong: adds unnecessary complexity
Solution to Avoid These Pitfalls:
- Follow the consumption sequence literally: Consume first, then check for transfer conditions
- Use simulation over formula: The step-by-step simulation naturally handles all edge cases
- Test with traced examples: Manually trace through small examples (like
mainTank = 5, additionalTank = 1
) to verify your logic matches expected behavior - Initialize counters at 0: This makes the modulo arithmetic straightforward and intuitive
Which of these properties could exist for a graph but not a tree?
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Recursion Recursion is one of the most important concepts in computer science Simply speaking recursion is the process of a function calling itself Using a real life analogy imagine a scenario where you invite your friends to lunch https assets algo monster recursion jpg You first call Ben and ask
Want a Structured Path to Master System Design Too? Don’t Miss This!