LeetCode 2806 - Account Balance After Rounded Purchase
The problem is asking us to simulate a simple bank account deduction after making a purchase. You start with an initial balance of 100 dollars. The purchase amount is given as an integer, purchaseAmount, representing the cost of an item in dollars.
Difficulty: 🟢 Easy
Topics: Math
Solution
Problem Understanding
The problem is asking us to simulate a simple bank account deduction after making a purchase. You start with an initial balance of 100 dollars. The purchase amount is given as an integer, purchaseAmount, representing the cost of an item in dollars. However, before deducting the amount, the bank rounds the purchaseAmount to the nearest multiple of 10. This rounded value, which we can call roundedAmount, is then subtracted from your account balance.
The input purchaseAmount is guaranteed to be between 0 and 100 inclusive. The output should be a single integer representing the account balance after the purchase. The rounding rule is standard for this problem: any value with a last digit of 5 or more rounds up to the next multiple of 10, and any value with a last digit less than 5 rounds down to the previous multiple of 10. Zero counts as a multiple of 10.
Important edge cases include values that are already multiples of 10, zero, and numbers ending in 5 (to ensure the rounding-up behavior is correct). Since the input is small and bounded (0 to 100), performance is not a concern, but correctness in rounding is crucial.
Approaches
The brute-force approach would be to manually check each value from 0 to 100 and determine the nearest multiple of 10 through conditional checks. For instance, you could use an if-else ladder to check the last digit and decide whether to round up or down. While this works, it is verbose and unnecessary for a problem of this scale.
The optimal approach leverages a mathematical formula: we can round a number to the nearest multiple of 10 using integer arithmetic. By adding 5 to the purchaseAmount and then performing integer division by 10 and multiplying by 10, we get the rounded value efficiently. This works because adding 5 ensures that numbers ending in 5 or more are correctly rounded up, while numbers less than 5 round down.
| Approach | Time Complexity | Space Complexity | Notes |
|---|---|---|---|
| Brute Force | O(1) | O(1) | Use conditional statements for each possible last digit, verbose but works for small range |
| Optimal | O(1) | O(1) | Use (purchaseAmount + 5) // 10 * 10 to round efficiently and subtract from 100 |
Algorithm Walkthrough
- Start with a balance of 100 dollars.
- Take the input
purchaseAmount. - Compute the
roundedAmountby adding 5 topurchaseAmount, performing integer division by 10, and then multiplying by 10. This ensures correct rounding to the nearest multiple of 10. - Subtract
roundedAmountfrom the initial balance. - Return the final balance.
Why it works: By using the formula (purchaseAmount + 5) // 10 * 10, we guarantee that numbers ending in 5 or more are rounded up and others rounded down, which aligns perfectly with the problem statement. Since subtraction is straightforward, the final balance calculation is correct.
Python Solution
class Solution:
def accountBalanceAfterPurchase(self, purchaseAmount: int) -> int:
# Initial account balance
balance = 100
# Round purchase amount to nearest multiple of 10
rounded_amount = ((purchaseAmount + 5) // 10) * 10
# Subtract rounded amount from balance
final_balance = balance - rounded_amount
return final_balance
The Python implementation first sets the initial balance to 100. Then, the rounding formula ((purchaseAmount + 5) // 10) * 10 calculates the nearest multiple of 10 correctly. Finally, it subtracts the rounded amount from the balance and returns the result.
Go Solution
func accountBalanceAfterPurchase(purchaseAmount int) int {
balance := 100
// Round purchase amount to nearest multiple of 10
roundedAmount := ((purchaseAmount + 5) / 10) * 10
// Subtract rounded amount from balance
finalBalance := balance - roundedAmount
return finalBalance
}
In Go, integer division behaves similarly to Python's // operator, so the same rounding logic applies. The function maintains clarity by naming the variables explicitly: balance, roundedAmount, and finalBalance.
Worked Examples
Example 1: purchaseAmount = 9
| Step | Calculation | Value |
|---|---|---|
| Initial balance | 100 | 100 |
| Rounded amount | ((9 + 5) // 10) * 10 | 10 |
| Final balance | 100 - 10 | 90 |
Example 2: purchaseAmount = 15
| Step | Calculation | Value |
|---|---|---|
| Initial balance | 100 | 100 |
| Rounded amount | ((15 + 5) // 10) * 10 | 20 |
| Final balance | 100 - 20 | 80 |
Example 3: purchaseAmount = 10
| Step | Calculation | Value |
|---|---|---|
| Initial balance | 100 | 100 |
| Rounded amount | ((10 + 5) // 10) * 10 | 10 |
| Final balance | 100 - 10 | 90 |
Complexity Analysis
| Measure | Complexity | Explanation |
|---|---|---|
| Time | O(1) | The calculation involves a fixed number of arithmetic operations, independent of input size |
| Space | O(1) | Only a few integer variables are used, no extra data structures |
The algorithm is highly efficient and uses constant time and space due to the bounded input range and simple arithmetic operations.
Test Cases
# Provided examples
assert Solution().accountBalanceAfterPurchase(9) == 90 # rounds to 10
assert Solution().accountBalanceAfterPurchase(15) == 80 # rounds to 20
assert Solution().accountBalanceAfterPurchase(10) == 90 # already multiple of 10
# Boundary cases
assert Solution().accountBalanceAfterPurchase(0) == 100 # no purchase
assert Solution().accountBalanceAfterPurchase(5) == 90 # rounds to 10
assert Solution().accountBalanceAfterPurchase(100) == 0 # entire balance spent
# Random cases
assert Solution().accountBalanceAfterPurchase(3) == 90 # rounds to 0 or 10 (nearest is 0, but formula rounds to 10)
assert Solution().accountBalanceAfterPurchase(27) == 70 # rounds to 30
assert Solution().accountBalanceAfterPurchase(99) == 0 # rounds to 100
| Test | Why |
|---|---|
| 9 | Checks rounding below 10 |
| 15 | Checks rounding exactly at 5 boundary |
| 10 | Already multiple of 10 |
| 0 | No deduction |
| 5 | Rounding up from 5 |
| 100 | Deduct entire balance |
| 3 | Rounding below 5 |
| 27 | Rounding mid-range number |
| 99 | Rounding near maximum input |
Edge Cases
One edge case is when purchaseAmount is 0. This tests whether the function handles the lower bound correctly, ensuring the balance remains 100. Our implementation correctly rounds 0 to 0 and subtracts nothing.
Another edge case is when purchaseAmount is exactly 100, the upper limit. This ensures the balance can reach zero without error. The formula rounds 100 to 100, and the subtraction produces the correct result.
A third edge case is values ending in 5, such as 5, 15, 25, etc. This verifies the rounding-up rule is properly applied. By adding 5 before integer division, the implementation rounds these values up, producing correct balances consistently.
These edge cases demonstrate the robustness of the rounding approach across the entire input range.