2457. Minimum Addition to Make Integer Beautiful
Problem Description
You are given two positive integers n
and target
.
An integer is called beautiful if the sum of its digits is less than or equal to target
.
Your task is to find the minimum non-negative integer x
such that n + x
becomes beautiful. In other words, you need to find the smallest value x ≥ 0
where the sum of digits of n + x
is at most target
.
For example:
- If
n = 16
andtarget = 6
, the sum of digits of16
is1 + 6 = 7
, which is greater than6
. So16
is not beautiful. - Adding
x = 4
gives us16 + 4 = 20
, with digit sum2 + 0 = 2 ≤ 6
, making20
beautiful. - The answer would be
4
since it's the minimum value needed.
The problem guarantees that it's always possible to make n
beautiful by adding some non-negative integer to it.
Intuition
The key insight is that to reduce the digit sum of a number, we should increase it to the next "round" number with trailing zeros. Numbers with trailing zeros have smaller digit sums because zeros don't contribute to the sum.
Consider what happens when we want to reduce the digit sum of a number like 467
. The digit sum is 4 + 6 + 7 = 17
. If we just add small values like 1
or 2
, we get 468
or 469
, which still have large digit sums. But if we round up to 470
, we eliminate the 7
in the ones place, reducing our digit sum to 4 + 7 + 0 = 11
.
The strategy is to repeatedly "round up" by eliminating the rightmost non-zero digit. When we change 467
to 470
, we're essentially making the last digit 0
and carrying over to the tens place. If the digit sum is still too large, we continue: 470
becomes 500
(eliminating the 7
in the tens place).
Why does this greedy approach work? Because each rounding operation:
- Reduces the digit sum by eliminating a non-zero digit and replacing it with zero
- Only increases higher-order digits by at most
1
- Creates the smallest possible increase that achieves this digit reduction
The algorithm finds the rightmost non-zero digit, rounds up at that position, and repeats until the digit sum meets our target. This ensures we add the minimum value to n
because we're making the smallest jumps necessary to reduce the digit sum at each step.
Solution Approach
The implementation follows the greedy strategy of repeatedly rounding up to eliminate non-zero digits from right to left.
First, we define a helper function f(x)
that calculates the sum of digits of an integer x
:
def f(x: int) -> int:
y = 0
while x:
y += x % 10
x //= 10
return y
The main algorithm starts with x = 0
and continues while f(n + x) > target
:
-
Calculate current value: Set
y = n + x
as the current number we're working with. -
Find the rightmost non-zero digit position:
- Initialize
p = 10
(representing the place value) - While
y % 10 == 0
(current digit is zero), dividey
by 10 and multiplyp
by 10 - This loop skips all trailing zeros to find the first non-zero digit from the right
- Initialize
-
Round up to eliminate the non-zero digit:
y // 10 + 1
gives us the number after removing the last digit and adding 1- Multiply by
p
to restore the correct place value with trailing zeros - Calculate the new
x
as(y // 10 + 1) * p - n
For example, with n = 467
:
- First iteration:
y = 467
, no trailing zeros,p = 10
x = (467 // 10 + 1) * 10 - 467 = 47 * 10 - 467 = 470 - 467 = 3
- Second iteration:
y = 470
, one trailing zero,p = 100
after the loopx = (47 // 10 + 1) * 100 - 467 = 5 * 100 - 467 = 500 - 467 = 33
- Now
f(500) = 5
, which is likely ≤ target, so we exit
The algorithm guarantees finding the minimum x
because at each step, we make the smallest possible jump that reduces the digit sum by eliminating exactly one non-zero digit.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's trace through the algorithm with n = 467
and target = 6
.
Initial State:
n = 467
, digit sum =4 + 6 + 7 = 17
(not beautiful since 17 > 6)x = 0
Iteration 1:
- Current value:
y = n + x = 467 + 0 = 467
- Digit sum of 467 is 17, which is > 6, so we continue
- Find rightmost non-zero digit:
467 % 10 = 7
(not zero), sop = 10
- Round up:
(467 // 10 + 1) * 10 = (46 + 1) * 10 = 470
- Update:
x = 470 - 467 = 3
Iteration 2:
- Current value:
y = n + x = 467 + 3 = 470
- Digit sum of 470 is
4 + 7 + 0 = 11
(still > 6) - Find rightmost non-zero digit:
470 % 10 = 0
(is zero), so divide:y = 47
,p = 100
47 % 10 = 7
(not zero), stop here withp = 100
- Round up:
(47 // 10 + 1) * 100 = (4 + 1) * 100 = 500
- Update:
x = 500 - 467 = 33
Iteration 3:
- Current value:
y = n + x = 467 + 33 = 500
- Digit sum of 500 is
5 + 0 + 0 = 5
(5 ≤ 6, beautiful!) - Algorithm terminates
Result: The minimum x = 33
makes 467 + 33 = 500
beautiful.
The algorithm efficiently jumps from 467 → 470 → 500, making the smallest increases needed to reduce the digit sum at each step.
Solution Implementation
1class Solution:
2 def makeIntegerBeautiful(self, n: int, target: int) -> int:
3 def calculate_digit_sum(number: int) -> int:
4 """Calculate the sum of all digits in a number."""
5 digit_sum = 0
6 while number:
7 digit_sum += number % 10
8 number //= 10
9 return digit_sum
10
11 # Initialize the amount to add to n
12 addition = 0
13
14 # Keep incrementing until the digit sum is <= target
15 while calculate_digit_sum(n + addition) > target:
16 current_number = n + addition
17 multiplier = 10
18
19 # Find the rightmost non-zero digit position
20 # by removing trailing zeros and tracking the multiplier
21 while current_number % 10 == 0:
22 current_number //= 10
23 multiplier *= 10
24
25 # Round up to the next number with fewer non-zero digits
26 # by incrementing the digit before the rightmost non-zero digit
27 # and setting all following digits to 0
28 addition = (current_number // 10 + 1) * multiplier - n
29
30 return addition
31
1class Solution {
2 /**
3 * Finds the minimum non-negative integer x such that n + x is beautiful.
4 * A number is beautiful if the sum of its digits is less than or equal to target.
5 *
6 * @param n The original number
7 * @param target The maximum allowed sum of digits
8 * @return The minimum value to add to n to make it beautiful
9 */
10 public long makeIntegerBeautiful(long n, int target) {
11 long addValue = 0;
12
13 // Keep incrementing until we find a beautiful number
14 while (calculateDigitSum(n + addValue) > target) {
15 long currentNumber = n + addValue;
16 long multiplier = 10;
17
18 // Find the rightmost non-zero digit position
19 // Skip all trailing zeros to find where we need to round up
20 while (currentNumber % 10 == 0) {
21 currentNumber /= 10;
22 multiplier *= 10;
23 }
24
25 // Round up to the next number with fewer non-zero digits
26 // This is done by incrementing the digit to the left of the rightmost non-zero digit
27 // and setting all digits to its right to zero
28 addValue = (currentNumber / 10 + 1) * multiplier - n;
29 }
30
31 return addValue;
32 }
33
34 /**
35 * Calculates the sum of digits of a given number.
36 *
37 * @param number The input number
38 * @return The sum of all digits
39 */
40 private int calculateDigitSum(long number) {
41 int digitSum = 0;
42
43 // Extract and sum each digit
44 while (number > 0) {
45 digitSum += number % 10; // Add the last digit
46 number /= 10; // Remove the last digit
47 }
48
49 return digitSum;
50 }
51}
52
1class Solution {
2public:
3 long long makeIntegerBeautiful(long long n, int target) {
4 using ll = long long;
5
6 // Lambda function to calculate the sum of digits of a number
7 auto calculateDigitSum = [](ll number) {
8 int digitSum = 0;
9 while (number > 0) {
10 digitSum += number % 10; // Add the last digit
11 number /= 10; // Remove the last digit
12 }
13 return digitSum;
14 };
15
16 ll addedValue = 0; // The value we need to add to n to make it beautiful
17
18 // Keep incrementing until the digit sum is at most target
19 while (calculateDigitSum(n + addedValue) > target) {
20 ll currentNumber = n + addedValue;
21 ll powerOfTen = 10;
22
23 // Find the first non-zero digit from the right
24 // and calculate the corresponding power of 10
25 while (currentNumber % 10 == 0) {
26 currentNumber /= 10;
27 powerOfTen *= 10;
28 }
29
30 // Round up to the next multiple of powerOfTen
31 // This effectively sets the current non-zero digit and all digits to its right to 0
32 // while incrementing the digit to its left by 1
33 addedValue = (currentNumber / 10 + 1) * powerOfTen - n;
34 }
35
36 return addedValue;
37 }
38};
39
1/**
2 * Makes an integer "beautiful" by finding the minimum value to add
3 * such that the sum of digits doesn't exceed the target.
4 * @param n - The original number to make beautiful
5 * @param target - The maximum allowed sum of digits
6 * @returns The minimum value to add to n
7 */
8function makeIntegerBeautiful(n: number, target: number): number {
9 /**
10 * Calculates the sum of digits of a given number
11 * @param num - The number whose digits to sum
12 * @returns The sum of all digits
13 */
14 const calculateDigitSum = (num: number): number => {
15 let digitSum = 0;
16
17 // Extract and sum each digit by repeatedly dividing by 10
18 while (num > 0) {
19 digitSum += num % 10; // Add the last digit
20 num = Math.floor(num / 10); // Remove the last digit
21 }
22
23 return digitSum;
24 };
25
26 let addValue = 0; // The value to add to n to make it beautiful
27
28 // Keep increasing addValue until the digit sum is within target
29 while (calculateDigitSum(n + addValue) > target) {
30 let currentNumber = n + addValue;
31 let multiplier = 10;
32
33 // Find the position of the first non-zero digit from the right
34 // by removing trailing zeros and tracking the multiplier
35 while (currentNumber % 10 === 0) {
36 currentNumber = Math.floor(currentNumber / 10);
37 multiplier *= 10;
38 }
39
40 // Round up to the next number with fewer significant digits
41 // This reduces the digit sum by eliminating lower digits
42 addValue = (Math.floor(currentNumber / 10) + 1) * multiplier - n;
43 }
44
45 return addValue;
46}
47
Time and Space Complexity
The time complexity is O(log² n)
, where n
is the given integer.
Time Complexity Analysis:
- The outer while loop continues as long as
f(n + x) > target
. In the worst case, we need to round upn
to the next power of 10, which takes at mostO(log n)
iterations (since we're dealing with digits). - Inside the outer loop:
- The function
f(x)
calculates the sum of digits, which takesO(log(n + x))
time, approximatelyO(log n)
sincex
is bounded by the next power of 10 relative ton
. - The inner while loop counts trailing zeros by repeatedly dividing by 10. This loop runs at most
O(log n)
times (the maximum number of digits).
- The function
- Therefore, the total time complexity is
O(log n) × O(log n) = O(log² n)
.
Space Complexity Analysis:
- The algorithm uses only a constant number of variables:
x
,y
, andp
. - The function
f(x)
also uses only constant extra space for its local variabley
. - No recursive calls or data structures that grow with input size are used.
- Therefore, the space complexity is
O(1)
.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Integer Overflow in Large Numbers
Pitfall: When dealing with very large values of n
, the intermediate calculations like (current_number // 10 + 1) * multiplier
might cause integer overflow in languages with fixed integer sizes. While Python handles arbitrary precision integers automatically, this could be problematic when implementing in languages like Java or C++.
Solution: In languages with fixed integer types, use long/long long data types or implement overflow checking:
# Python handles this automatically, but in other languages: # Check if multiplication would overflow before performing it if current_number // 10 + 1 > MAX_VALUE // multiplier: # Handle overflow case pass
2. Incorrect Handling of Already Beautiful Numbers
Pitfall: The code might perform unnecessary iterations if n
is already beautiful. While the while loop condition handles this correctly, developers might accidentally add extra logic that processes already beautiful numbers.
Solution: Always check the condition first:
# Explicitly check if n is already beautiful if calculate_digit_sum(n) <= target: return 0 # Then proceed with the main algorithm addition = 0 while calculate_digit_sum(n + addition) > target: # ... rest of the logic
3. Misunderstanding the Rounding Logic
Pitfall: The expression (current_number // 10 + 1) * multiplier
might be confusing. Developers might incorrectly think they need to round to the nearest 10, 100, etc., rather than incrementing to the next higher value with trailing zeros.
Example of incorrect approach:
# WRONG: Simply rounding to nearest 10 addition = ((n + 9) // 10) * 10 - n # This doesn't minimize x # CORRECT: The algorithm's approach # Systematically eliminates rightmost non-zero digits
4. Inefficient Digit Sum Calculation
Pitfall: Repeatedly calculating the digit sum from scratch for each iteration can be inefficient, especially for very large numbers with many digits.
Solution: While the current approach is correct, for optimization you could track how the digit sum changes:
def makeIntegerBeautiful(self, n: int, target: int) -> int:
def calculate_digit_sum(number: int) -> int:
digit_sum = 0
while number:
digit_sum += number % 10
number //= 10
return digit_sum
# Cache the initial digit sum
current_sum = calculate_digit_sum(n)
if current_sum <= target:
return 0
addition = 0
while calculate_digit_sum(n + addition) > target:
# ... existing logic
5. Edge Case with Small Targets
Pitfall: When target
is very small (like 1 or 2), the algorithm might need many iterations to reach a beautiful number, potentially causing performance issues.
Solution: For very small targets, consider jumping directly to powers of 10:
# Special handling for very small targets if target == 1: # Find the next power of 10 power = 1 while power <= n: power *= 10 return power - n
Which two pointer techniques do you use to check if a string is a palindrome?
Recommended Readings
Greedy Introduction div class responsive iframe iframe src https www youtube com embed WTslqPbj7I title YouTube video player frameborder 0 allow accelerometer autoplay clipboard write encrypted media gyroscope picture in picture web share allowfullscreen iframe div When do we use greedy Greedy algorithms tend to solve optimization problems Typically they will ask you to calculate the max min of some value Commonly you may see this phrased in the problem as max min longest shortest largest smallest etc These keywords can be identified by just scanning
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
Want a Structured Path to Master System Design Too? Don’t Miss This!