Editorial
Solution walkthrough
Review the explanation, then compare the reference implementation.
Video explanation
Solution
Intuition
After drinking the initial bottles, all of them are empty and available for exchange. Each exchange batch creates new full bottles, which become new empties after drinking; leftover empties must also carry into the next round.
Approach
Start the total at the initial bottle count. While there are enough empties, exchange as many full groups as possible, add the received bottles to the total, and set the new empty count to the received bottles plus the old remainder. Stop when fewer than numExchange empties remain. The exchange rate is at least two, so this process eventually stops; discarding the remainder would incorrectly lose future exchanges.
class Solution:
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
res = numBottles
while numBottles >= numExchange:
drink = numBottles // numExchange
res += drink
numBottles = drink + (numBottles % numExchange)
return resComplexity analysis
Let B = numBottles and E = numExchange ≥ 2. Each round reduces the active bottle count by roughly a factor of E, so the batched simulation uses O(log_E B) time and O(1) auxiliary space.
