LeetCode Challenge Day 16 β 1518. Water Bottles
Nitin Ahirwal / October 1, 2025
Hey folks
This is Day 16 of my LeetCode streak π.
Todayβs problem is 1518. Water Bottles β weβre given some initial full bottles and a rule for exchanging empty ones. The goal is to figure out the maximum number of bottles we can drink.
Itβs a classic simulation-style problem with a neat greedy loop.
π Problem Statement
You are given two integers:
numBottlesβ the number of full water bottles you initially have.numExchangeβ the number of empty bottles required to exchange for one new full bottle.
Each time you drink a bottle, it becomes empty. You can keep exchanging empty bottles for new full bottles until no further exchanges are possible.
Return the maximum number of bottles you can drink.
Examples
-
Input:
numBottles = 9, numExchange = 3
Output:13
Explanation: Drink 9 β exchange for 3 β drink 3 β exchange for 1 β drink 1 β total = 13. -
Input:
numBottles = 15, numExchange = 4
Output:19
Explanation: Drink 15 β exchange for 3 β drink 3 β exchange for 1 β drink 1 β total = 19.
Constraints
1 <= numBottles <= 1002 <= numExchange <= 100
π‘ Intuition
The problem mimics real life:
- Drink all bottles you have.
- Count the empty ones.
- Trade empties for full bottles as long as possible.
This can be directly simulated with a loop β each exchange reduces empty bottles and adds new full ones.
π Approach
- Start with
totalDrunk = numBottles. - Keep a counter of empty bottles.
- While you have at least
numExchangeempties:- Exchange them for new full bottles.
- Add the new bottles to
totalDrunk. - Update the empty count as
(empties % numExchange) + newBottles.
- Once no more exchanges are possible, return
totalDrunk.
β±οΈ Complexity Analysis
- Time complexity:
O(log numBottles)β since bottles reduce quickly per exchange. - Space complexity:
O(1)β only a few variables are used.
π§βπ» Code (JavaScript)
/**
* @param {number} numBottles
* @param {number} numExchange
* @return {number}
*/
var numWaterBottles = function(numBottles, numExchange) {
let totalDrunk = numBottles;
let empty = numBottles;
while (empty >= numExchange) {
let newBottles = Math.floor(empty / numExchange);
totalDrunk += newBottles;
empty = (empty % numExchange) + newBottles;
}
return totalDrunk;
};
// β
Quick tests
console.log(numWaterBottles(9, 3)); // 13
console.log(numWaterBottles(15, 4)); // 19
π§ͺ Edge Cases
-
numBottles < numExchange β no exchange possible, answer =
numBottles. -
Exactly divisible β the loop continues until 1 empty remains.
-
Small inputs β works fine since constraints are tiny.
π₯ Reflections
This problem highlights how simple simulation loops can solve real-world style challenges.
Itβs not always about math shortcuts β sometimes just carefully simulating step by step is the cleanest approach.
Thatβs it for Day 16 of my LeetCode journey!
On to the next challenge π₯
Happy Coding π¨βπ»