2165. Smallest Value of the Rearranged Number
Problem Description
You are given an integer num
. Your task is to rearrange the digits of this number to create the smallest possible value, with the constraint that the result cannot have leading zeros.
The key requirements are:
- Rearrange the digits of the given number to minimize its value
- No leading zeros are allowed in the result (except for the number 0 itself)
- The sign of the number (positive or negative) must remain the same after rearrangement
For example:
- If
num = 310
, the smallest rearrangement would be103
(not013
since leading zeros aren't allowed) - If
num = -7605
, the smallest negative number would be-7650
(arranging digits to make the largest absolute value gives the smallest negative number)
The solution uses a counting approach where it tracks the frequency of each digit (0-9) in the input number. For negative numbers, digits are arranged in descending order to maximize the absolute value (making the negative number as small as possible). For positive numbers, the smallest non-zero digit is placed first to avoid leading zeros, followed by all remaining digits in ascending order.
Intuition
To find the smallest possible number after rearranging digits, we need to think about how digit placement affects the value of a number. In any number, digits in higher positions (leftmost) contribute more to the overall value than digits in lower positions (rightmost). For instance, in the number 321
, the digit 3
contributes 300
, while 1
contributes only 1
.
For positive numbers, we want smaller digits on the left to minimize the value. The natural approach would be to sort all digits in ascending order. However, there's a catch - we cannot have leading zeros. So if we have zeros in our number, we can't place them at the beginning. This means we need to find the smallest non-zero digit, place it first, then arrange all remaining digits (including zeros) in ascending order after it.
For negative numbers, the logic flips. To get the smallest negative number, we actually need the largest absolute value. Think about it: -9
is smaller than -1
even though 9 > 1
. Therefore, for negative numbers, we want to arrange digits in descending order to maximize the absolute value, which gives us the minimum negative value.
The counting approach emerges naturally from this understanding. Instead of manipulating the digits directly, we can:
- Count how many times each digit (0-9) appears in the original number
- Reconstruct the number by placing digits according to our strategy:
- For positive: smallest non-zero digit first, then all others in ascending order
- For negative: all digits in descending order
This counting method is efficient because we only need to iterate through digits once to count them, and once more to build the result, making it a linear time solution relative to the number of digits.
Solution Approach
The solution uses a counting sort approach with an array to track digit frequencies. Here's the step-by-step implementation:
1. Initialize and Count Digits
- Create a counting array
cnt
of size 10 to store the frequency of each digit (0-9) - Determine if the number is negative and work with its absolute value
- Extract each digit using modulo operation (
num % 10
) and integer division (num // 10
) - Increment the count for each digit found
2. Handle Negative Numbers For negative numbers, we want the largest absolute value (to get the smallest negative):
- Traverse the
cnt
array from 9 down to 0 (descending order) - For each digit
i
that appearscnt[i]
times:- Multiply the answer by 10 and add the digit
i
- Repeat this
cnt[i]
times
- Multiply the answer by 10 and add the digit
- Return the negative of the constructed number
3. Handle Positive Numbers For positive numbers, we need to avoid leading zeros:
- First, check if there are any zeros (
cnt[0] > 0
) - If zeros exist, find the smallest non-zero digit:
- Iterate from 1 to 9 to find the first digit with
cnt[i] > 0
- Set this as the starting digit of our answer
- Decrement its count by 1
- Iterate from 1 to 9 to find the first digit with
- Then arrange all remaining digits in ascending order:
- Traverse from 0 to 9
- For each digit
i
that appearscnt[i]
times:- Multiply the answer by 10 and add the digit
i
- Repeat this
cnt[i]
times
- Multiply the answer by 10 and add the digit
4. Build the Result
The number is constructed digit by digit using the formula: ans = ans * 10 + digit
. This effectively shifts existing digits left and adds the new digit at the rightmost position.
The time complexity is O(d)
where d
is the number of digits, and space complexity is O(1)
since the counting array has a fixed size of 10.
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 walk through the solution with num = 310
:
Step 1: Initialize and Count Digits
- Create counting array
cnt = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
- Number is positive, so we'll use positive number logic
- Extract digits:
- 310 % 10 = 0, so cnt[0]++, now
cnt = [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
, num becomes 31 - 31 % 10 = 1, so cnt[1]++, now
cnt = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0]
, num becomes 3 - 3 % 10 = 3, so cnt[3]++, now
cnt = [1, 1, 0, 1, 0, 0, 0, 0, 0, 0]
, num becomes 0
- 310 % 10 = 0, so cnt[0]++, now
Step 2: Handle Positive Number with Leading Zero Prevention
- Check if zeros exist: cnt[0] = 1, so yes
- Find smallest non-zero digit:
- Check cnt[1] = 1 > 0, found it!
- Start answer with 1:
ans = 1
- Decrement cnt[1] to 0:
cnt = [1, 0, 0, 1, 0, 0, 0, 0, 0, 0]
Step 3: Add Remaining Digits in Ascending Order
- Traverse cnt from index 0 to 9:
- cnt[0] = 1: Add one 0:
ans = 1 * 10 + 0 = 10
- cnt[1] = 0: Skip
- cnt[2] = 0: Skip
- cnt[3] = 1: Add one 3:
ans = 10 * 10 + 3 = 103
- cnt[4] through cnt[9] = 0: Skip all
- cnt[0] = 1: Add one 0:
Result: 103
Now let's trace through a negative example with num = -7605
:
Step 1: Count Digits
- Working with absolute value 7605
- After counting:
cnt = [1, 0, 0, 0, 0, 1, 1, 1, 0, 0]
(one 0, one 5, one 6, one 7)
Step 2: Handle Negative Number (Descending Order)
- Start from digit 9 down to 0:
- cnt[9] = 0: Skip
- cnt[8] = 0: Skip
- cnt[7] = 1: Add one 7:
ans = 0 * 10 + 7 = 7
- cnt[6] = 1: Add one 6:
ans = 7 * 10 + 6 = 76
- cnt[5] = 1: Add one 5:
ans = 76 * 10 + 5 = 765
- cnt[4] through cnt[1] = 0: Skip all
- cnt[0] = 1: Add one 0:
ans = 765 * 10 + 0 = 7650
Step 3: Apply Negative Sign
- Return
-7650
Result: -7650
Solution Implementation
1class Solution:
2 def smallestNumber(self, num: int) -> int:
3 # Check if the number is negative
4 is_negative = num < 0
5
6 # Work with absolute value
7 num = abs(num)
8
9 # Count frequency of each digit (0-9)
10 digit_count = [0] * 10
11
12 # Extract and count all digits
13 while num > 0:
14 digit_count[num % 10] += 1
15 num //= 10
16
17 # Initialize result
18 result = 0
19
20 if is_negative:
21 # For negative numbers, arrange digits in descending order
22 # to get the largest absolute value (smallest negative number)
23 for digit in range(9, -1, -1):
24 for _ in range(digit_count[digit]):
25 result = result * 10 + digit
26 return -result
27
28 # For positive numbers, handle leading zeros
29 if digit_count[0] > 0:
30 # Find the smallest non-zero digit to place first
31 for digit in range(1, 10):
32 if digit_count[digit] > 0:
33 result = digit
34 digit_count[digit] -= 1
35 break
36
37 # Append remaining digits in ascending order
38 for digit in range(10):
39 for _ in range(digit_count[digit]):
40 result = result * 10 + digit
41
42 return result
43
1class Solution {
2 public long smallestNumber(long num) {
3 // Check if the number is negative
4 boolean isNegative = num < 0;
5
6 // Work with absolute value
7 num = Math.abs(num);
8
9 // Count frequency of each digit (0-9)
10 int[] digitCount = new int[10];
11 while (num > 0) {
12 digitCount[(int) (num % 10)]++;
13 num /= 10;
14 }
15
16 long result = 0;
17
18 // Handle negative numbers - arrange digits in descending order
19 if (isNegative) {
20 for (int digit = 9; digit >= 0; digit--) {
21 while (digitCount[digit] > 0) {
22 result = result * 10 + digit;
23 digitCount[digit]--;
24 }
25 }
26 return -result; // Return negative value
27 }
28
29 // Handle positive numbers with leading zeros
30 // Place the smallest non-zero digit first to avoid leading zeros
31 if (digitCount[0] > 0) {
32 for (int digit = 1; digit <= 9; digit++) {
33 if (digitCount[digit] > 0) {
34 digitCount[digit]--;
35 result = digit;
36 break;
37 }
38 }
39 }
40
41 // Append remaining digits in ascending order (including zeros)
42 for (int digit = 0; digit <= 9; digit++) {
43 while (digitCount[digit] > 0) {
44 result = result * 10 + digit;
45 digitCount[digit]--;
46 }
47 }
48
49 return result;
50 }
51}
52
1class Solution {
2public:
3 long long smallestNumber(long long num) {
4 // Check if the number is negative
5 bool isNegative = num < 0;
6
7 // Work with absolute value
8 num = abs(num);
9
10 // Count frequency of each digit (0-9)
11 int digitCount[10] = {0};
12 while (num > 0) {
13 digitCount[num % 10]++;
14 num /= 10;
15 }
16
17 long long result = 0;
18
19 // If original number was negative, create the largest absolute value
20 // (which becomes smallest when negated)
21 if (isNegative) {
22 // Build number from largest to smallest digit
23 for (int digit = 9; digit >= 0; digit--) {
24 while (digitCount[digit] > 0) {
25 result = result * 10 + digit;
26 digitCount[digit]--;
27 }
28 }
29 // Return negative value
30 return -result;
31 }
32
33 // For positive numbers, handle leading zeros
34 // If there are zeros, we need to place the smallest non-zero digit first
35 if (digitCount[0] > 0) {
36 // Find and place the smallest non-zero digit at the beginning
37 for (int digit = 1; digit <= 9; digit++) {
38 if (digitCount[digit] > 0) {
39 digitCount[digit]--;
40 result = digit;
41 break;
42 }
43 }
44 }
45
46 // Append remaining digits in ascending order (including zeros)
47 for (int digit = 0; digit <= 9; digit++) {
48 while (digitCount[digit] > 0) {
49 result = result * 10 + digit;
50 digitCount[digit]--;
51 }
52 }
53
54 return result;
55 }
56};
57
1/**
2 * Rearranges the digits of a number to form the smallest possible number
3 * @param num - The input number to rearrange
4 * @returns The smallest number possible by rearranging the digits
5 */
6function smallestNumber(num: number): number {
7 // Check if the number is negative
8 const isNegative: boolean = num < 0;
9
10 // Work with absolute value
11 num = Math.abs(num);
12
13 // Count frequency of each digit (0-9)
14 const digitCount: number[] = Array(10).fill(0);
15
16 // Extract and count each digit
17 while (num > 0) {
18 digitCount[num % 10]++;
19 num = Math.floor(num / 10);
20 }
21
22 let result: number = 0;
23
24 // Handle negative numbers: arrange digits in descending order
25 if (isNegative) {
26 for (let digit: number = 9; digit >= 0; digit--) {
27 while (digitCount[digit] > 0) {
28 result = result * 10 + digit;
29 digitCount[digit]--;
30 }
31 }
32 return -result;
33 }
34
35 // Handle positive numbers with leading zeros
36 // Place the smallest non-zero digit first to avoid leading zeros
37 if (digitCount[0] > 0) {
38 for (let digit: number = 1; digit < 10; digit++) {
39 if (digitCount[digit] > 0) {
40 digitCount[digit]--;
41 result = digit;
42 break;
43 }
44 }
45 }
46
47 // Append remaining digits in ascending order for smallest positive number
48 for (let digit: number = 0; digit < 10; digit++) {
49 while (digitCount[digit] > 0) {
50 result = result * 10 + digit;
51 digitCount[digit]--;
52 }
53 }
54
55 return result;
56}
57
Time and Space Complexity
The time complexity is O(log n)
, where n
is the absolute value of the input number num
. This is because:
- The first while loop extracts digits by repeatedly dividing by 10, which takes
O(log n)
iterations (the number of digits inn
) - The reconstruction loops iterate through the fixed array of size 10, and for each position, iterate based on the count of that digit. The total iterations across all digits equals the number of digits in the original number, which is
O(log n)
The space complexity is O(1)
. The algorithm uses:
- A fixed-size array
cnt
of length 10 to store digit counts - A few constant variables (
neg
,num
,ans
,i
) - Since the array size is constant (always 10) regardless of input size, the space usage remains constant
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Not Handling the Special Case of Zero
One of the most common pitfalls is forgetting that when the input is 0
, the function should return 0
directly. The current implementation handles this correctly because when num = 0
, the while loop doesn't execute (since 0 > 0
is false), leaving all digit counts at 0, and the result naturally becomes 0.
Problem Example:
# If not handled properly, num = 0 might cause issues # Some implementations might try to extract digits and fail
Solution: Add an explicit check at the beginning:
if num == 0: return 0
2. Integer Overflow for Large Numbers
When building the result by repeatedly multiplying by 10 and adding digits, very large numbers might cause integer overflow in languages with fixed integer sizes. Python handles arbitrary precision integers, but this could be an issue in other languages.
Problem Example:
# For very large numbers like 9999999999999999 # In languages like Java/C++, this could overflow
Solution: In Python, this isn't an issue, but in other languages, consider using long integers or checking for overflow:
# Check if result will overflow before multiplication if result > (2**31 - 1) // 10: # Handle overflow case pass
3. Incorrectly Handling Negative Numbers with Leading Zeros After Rearrangement
A subtle pitfall occurs when dealing with negative numbers that have zeros. The algorithm must ensure zeros are placed optimally to minimize the absolute value.
Problem Example:
# For num = -7605 # Incorrect: -0567 (invalid) or -5067 (not optimal) # Correct: -7650 (largest absolute value = smallest negative)
Solution: The current implementation handles this correctly by arranging digits in descending order for negative numbers, which naturally places zeros at the end.
4. Forgetting to Restore the Sign
After processing the absolute value, forgetting to restore the negative sign is a common mistake.
Problem Example:
# Processing num = -321 # Forgetting to add back the negative sign would return 123 instead of -321
Solution: Always remember to negate the result for negative inputs:
if is_negative: return -result # Don't forget the negative sign!
5. Edge Case: All Zeros Except One Non-Zero Digit
When a positive number consists of mostly zeros with just one non-zero digit, ensuring proper placement is crucial.
Problem Example:
# For num = 1000 # Incorrect: 0001 (leading zeros not allowed) # Correct: 1000
Solution: The algorithm correctly handles this by:
- Finding the smallest non-zero digit first
- Placing it at the beginning
- Then appending all zeros
This ensures no leading zeros while maintaining the smallest possible value.
Which of the following is a min heap?
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
Sorting Summary Comparisons We presented quite a few sorting algorithms and it is essential to know the advantages and disadvantages of each one The basic algorithms are easy to visualize and easy to learn for beginner programmers because of their simplicity As such they will suffice if you don't know any advanced
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!