Back to posts

LeetCode Challenge Day 16 β€” 1518. Water Bottles

Nitin Ahirwal / October 1, 2025

LeetCode ChallengeDay 16SimulationJavaScriptGreedyEasyPortfolio

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 <= 100
  • 2 <= 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

  1. Start with totalDrunk = numBottles.
  2. Keep a counter of empty bottles.
  3. While you have at least numExchange empties:
    • Exchange them for new full bottles.
    • Add the new bottles to totalDrunk.
    • Update the empty count as (empties % numExchange) + newBottles.
  4. 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 πŸ‘¨β€πŸ’»