2806. Account Balance After Rounded Purchase
Problem Description
You start with a bank account balance of 100 dollars.
When you make a purchase for purchaseAmount
dollars, the following happens:
- The
purchaseAmount
is first rounded to the nearest multiple of 10 (let's call thisroundedAmount
) - Then
roundedAmount
dollars are deducted from your bank account
The rounding follows these rules:
- Any multiple of 10 (including 0) stays the same
- Values exactly halfway between two multiples of 10 round up (e.g., 5 rounds to 10, 15 rounds to 20, 25 rounds to 30)
- Other values round to the nearest multiple of 10
Your task is to return your final bank account balance after the purchase.
For example:
- If
purchaseAmount = 9
, it rounds to 10, so you'd have 100 - 10 = 90 dollars left - If
purchaseAmount = 15
, it rounds to 20, so you'd have 100 - 20 = 80 dollars left - If
purchaseAmount = 24
, it rounds to 20, so you'd have 100 - 20 = 80 dollars left
Intuition
The key insight is that we need to find which multiple of 10 is closest to our purchaseAmount
. Since we're dealing with a limited range (purchases between 0 and 100), we can check all possible multiples of 10: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100
.
For each multiple of 10, we calculate how far it is from purchaseAmount
using the absolute difference. The multiple with the smallest difference is our rounded value. When two multiples are equally close (like 15 being 5 away from both 10 and 20), we choose the larger one according to the rounding rules.
The solution iterates through all multiples of 10 from 100 down to 0. By going in descending order, when we find a new minimum difference, we naturally handle the "round up on ties" rule - if two values have the same difference, we keep the first one we found (which is the larger value due to our descending iteration).
Once we find the closest multiple of 10 (stored as x
), the final balance is simply 100 - x
, since we started with 100 dollars and spent x
dollars.
The approach works because:
- We're exhaustively checking all possible rounded values
- The absolute difference tells us which is closest
- The iteration order ensures ties are broken correctly (rounding up)
Learn more about Math patterns.
Solution Approach
The solution uses enumeration and simulation to find the correct rounded amount.
We initialize two variables:
diff = 100
: Tracks the minimum difference found so far (initialized to a large value)x = 0
: Stores the multiple of 10 that has the minimum difference
We iterate through all multiples of 10 from 100 down to 0 using range(100, -1, -10)
. This gives us the sequence: 100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0
.
For each multiple y
:
- Calculate the absolute difference:
t = abs(y - purchaseAmount)
- If this difference
t
is smaller than our current minimumdiff
:- Update
diff = t
(new minimum difference) - Update
x = y
(the multiple of 10 with minimum difference)
- Update
The key points of this approach:
- By iterating from 100 to 0 (descending order), when two multiples have the same distance from
purchaseAmount
, we keep the larger one (which we encountered first). This naturally handles the "round up on ties" rule. - We only update
x
when we find a strictly smaller difference (t < diff
), not when equal (t <= diff
), ensuring ties go to the higher value.
After finding the closest multiple of 10 stored in x
, we return 100 - x
as the final bank balance.
For example, if purchaseAmount = 15
:
- When
y = 20
: difference =|20 - 15| = 5
- When
y = 10
: difference =|10 - 15| = 5
- Since we check 20 first and both have the same difference,
x
remains 20 - Final balance =
100 - 20 = 80
Ready to land your dream job?
Unlock your dream job with a 3-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through the solution with purchaseAmount = 25
.
Step 1: Initialize tracking variables
diff = 100
(minimum difference found so far)x = 0
(the multiple of 10 with minimum difference)
Step 2: Iterate through multiples of 10 from 100 to 0
-
y = 100:
- difference = |100 - 25| = 75
- Since 75 < 100, update:
diff = 75
,x = 100
-
y = 90:
- difference = |90 - 25| = 65
- Since 65 < 75, update:
diff = 65
,x = 90
-
y = 80:
- difference = |80 - 25| = 55
- Since 55 < 65, update:
diff = 55
,x = 80
-
y = 70:
- difference = |70 - 25| = 45
- Since 45 < 55, update:
diff = 45
,x = 70
-
y = 60:
- difference = |60 - 25| = 35
- Since 35 < 45, update:
diff = 35
,x = 60
-
y = 50:
- difference = |50 - 25| = 25
- Since 25 < 35, update:
diff = 25
,x = 50
-
y = 40:
- difference = |40 - 25| = 15
- Since 15 < 25, update:
diff = 15
,x = 40
-
y = 30:
- difference = |30 - 25| = 5
- Since 5 < 15, update:
diff = 5
,x = 30
-
y = 20:
- difference = |20 - 25| = 5
- Since 5 is NOT less than 5 (it's equal), we don't update.
x
remains 30
-
y = 10:
- difference = |10 - 25| = 15
- Since 15 > 5, we don't update.
x
remains 30
-
y = 0:
- difference = |0 - 25| = 25
- Since 25 > 5, we don't update.
x
remains 30
Step 3: Calculate final balance
- The closest multiple of 10 is
x = 30
- Final balance = 100 - 30 = 70 dollars
Notice how when we had a tie (both 30 and 20 were 5 away from 25), we kept 30 because we encountered it first in our descending iteration. This ensures we round up when exactly halfway between two multiples of 10.
Solution Implementation
1class Solution:
2 def accountBalanceAfterPurchase(self, purchaseAmount: int) -> int:
3 # Initialize variables to track minimum difference and closest multiple
4 min_difference = 100
5 closest_multiple = 0
6
7 # Iterate through all multiples of 10 from 100 down to 0
8 for multiple_of_ten in range(100, -1, -10):
9 # Calculate the absolute difference between current multiple and purchase amount
10 current_difference = abs(multiple_of_ten - purchaseAmount)
11
12 # Update if we found a closer multiple of 10
13 if current_difference < min_difference:
14 min_difference = current_difference
15 closest_multiple = multiple_of_ten
16
17 # Return the remaining balance after deducting the rounded amount
18 # Initial balance is 100, subtract the closest multiple of 10
19 return 100 - closest_multiple
20
1class Solution {
2 public int accountBalanceAfterPurchase(int purchaseAmount) {
3 // Initialize variables to track the minimum difference and closest rounded amount
4 int minDifference = 100;
5 int closestRoundedAmount = 0;
6
7 // Iterate through all possible multiples of 10 from 100 down to 0
8 for (int currentMultiple = 100; currentMultiple >= 0; currentMultiple -= 10) {
9 // Calculate the absolute difference between current multiple and purchase amount
10 int currentDifference = Math.abs(currentMultiple - purchaseAmount);
11
12 // Update the closest rounded amount if we found a smaller difference
13 if (currentDifference < minDifference) {
14 minDifference = currentDifference;
15 closestRoundedAmount = currentMultiple;
16 }
17 }
18
19 // Return the remaining balance after subtracting the rounded amount from 100
20 return 100 - closestRoundedAmount;
21 }
22}
23
1class Solution {
2public:
3 int accountBalanceAfterPurchase(int purchaseAmount) {
4 // Find the closest multiple of 10 to the purchase amount
5 // Initial balance is 100
6
7 int minDifference = 100; // Track minimum difference found
8 int closestMultiple = 0; // Store the closest multiple of 10
9
10 // Iterate through all multiples of 10 from 100 down to 0
11 for (int currentMultiple = 100; currentMultiple >= 0; currentMultiple -= 10) {
12 // Calculate absolute difference between current multiple and purchase amount
13 int currentDifference = abs(currentMultiple - purchaseAmount);
14
15 // Update if we found a closer multiple
16 if (currentDifference < minDifference) {
17 minDifference = currentDifference;
18 closestMultiple = currentMultiple;
19 }
20 }
21
22 // Return remaining balance after spending the closest multiple
23 return 100 - closestMultiple;
24 }
25};
26
1/**
2 * Calculates the account balance after making a purchase with rounding to nearest 10
3 * @param purchaseAmount - The amount of the purchase to be made
4 * @returns The remaining account balance after the rounded purchase
5 */
6function accountBalanceAfterPurchase(purchaseAmount: number): number {
7 // Initialize variables to track minimum difference and corresponding rounded amount
8 let minDifference: number = 100;
9 let roundedAmount: number = 0;
10
11 // Iterate through all possible multiples of 10 from 100 down to 0
12 for (let currentMultiple: number = 100; currentMultiple >= 0; currentMultiple -= 10) {
13 // Calculate the absolute difference between current multiple and purchase amount
14 const difference: number = Math.abs(currentMultiple - purchaseAmount);
15
16 // Update the rounded amount if we found a closer multiple of 10
17 if (difference < minDifference) {
18 minDifference = difference;
19 roundedAmount = currentMultiple;
20 }
21 }
22
23 // Return the remaining balance after deducting the rounded purchase amount
24 return 100 - roundedAmount;
25}
26
Time and Space Complexity
The time complexity is O(1)
. The loop iterates through the range from 100 to 0 with a step of -10, which means it runs exactly 11 times (100, 90, 80, 70, 60, 50, 40, 30, 20, 10, 0). Since the number of iterations is fixed and does not depend on the input size, the time complexity is constant.
The space complexity is O(1)
. The algorithm only uses a fixed number of variables (diff
, x
, y
, and t
) regardless of the input value. No additional data structures that scale with input are created, so the space usage remains constant.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Handling of Tie-Breaking Rules
The Pitfall: When the purchase amount is exactly halfway between two multiples of 10 (e.g., 5, 15, 25), many developers incorrectly round down instead of up, or iterate in the wrong direction.
Why it happens:
- Using ascending iteration (0 to 100) with
<=
comparison would incorrectly favor the lower value - Standard rounding functions like
round()
may not follow the specific "round half up" rule required here
Incorrect approach example:
# Wrong: iterating in ascending order with <= comparison
for multiple_of_ten in range(0, 101, 10):
current_difference = abs(multiple_of_ten - purchaseAmount)
if current_difference <= min_difference: # Wrong: uses <=
min_difference = current_difference
closest_multiple = multiple_of_ten
# This would round 15 to 10 instead of 20
Solution:
- Iterate in descending order (100 to 0)
- Use strict less than (
<
) comparison, not less than or equal (<=
) - This ensures that when two multiples have equal distance, we keep the first one encountered (the larger value)
2. Using Mathematical Rounding Instead of Enumeration
The Pitfall: Attempting to use mathematical formulas or built-in rounding functions that don't match the problem's specific requirements.
Incorrect approach example:
# Wrong: Python's round() uses "round half to even" (banker's rounding)
rounded = round(purchaseAmount / 10) * 10
# This would round 15 to 20 (correct) but 25 to 20 (incorrect - should be 30)
# Also wrong: simple mathematical rounding
rounded = int(purchaseAmount / 10 + 0.5) * 10
# This fails for edge cases
Solution:
- Use explicit enumeration to check all multiples of 10
- This guarantees correct behavior for all edge cases without relying on language-specific rounding implementations
3. Off-by-One Errors in Range
The Pitfall: Not including all necessary multiples of 10 in the search range.
Incorrect approach example:
# Wrong: missing 0 or 100 in the range
for multiple_of_ten in range(10, 100, 10): # Missing 0 and 100
# ...
Solution:
- Ensure the range includes both 0 and 100:
range(100, -1, -10)
- The
-1
as the stop value is crucial because Python's range is exclusive of the stop value
You are given an array of intervals where intervals[i] = [start_i, end_i]
represent the start and end of the ith
interval. You need to merge all overlapping intervals and return an array of the non-overlapping intervals that cover all the intervals in the input.
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!