Problem
We need to reverse a provider integer (i32
) number num
without converting it to a string or using axillary data structures. Also, we should take care of a possible i32
overflow when reversing the number - in that case, we should return 0
.
Examples:
Input num | Output | Explanation |
1234 | 4321 | |
120 | 21 | |
1 | 1 | |
0 | 0 | |
-1 | -1 | |
-1234 | -4321 | |
1463847412 | 2147483641 | |
1463847413 | 0 | The reversed number would be greater than i32::MAX = 2147483647 |
-1463847413 | 0 | The reversed number would be less than i32::MIN = -2147483648 |
Solution
fn reverse_number(mut num: i32) -> i32 {
let mut num_reversed: i32 = 0;
while num != 0 {
if num_reversed.abs() > i32::MAX / 10 {
return 0;
} else {
num_reversed = num_reversed * 10 + num % 10;
num /= 10;
}
}
num_reversed
}
Explanation
This puzzle is similar to what we implemented in Check if a number is Palindrome puzzle. The idea is to decompose the original num
in the loop, digit by digit from the right, using the division and modulo operations, and at the same time compose a reversed number from these digits. The catch here is to avoid a possible i32
overflow in case we try to reverse some very large i32
number like 1463847413
. This number itself could fit in i32
range (it is less than i32::MAX = 2147483647
) but the reversed number would not fit. In that case, we should return 0
.
Let's consider the process step by step for num = 1234
.
On the 1st iteration,
num_reversed = num_reversed * 10 + num % 10 = 0 * 10 + 1234 % 10 = 4
. This is the last digit of1234
. Then we also updatenum = num / 10 = 1234 / 10 = 123
.On the 2nd iteration,
num_reversed = num_reversed * 10 + num % 10 = 4 * 10 + 123 % 10 = 43
. That is the last 2 reversed digits of1234
. Then we also updatenum = num / 10 = 123 / 10 = 12
.On the 3rd iteration,
num_reversed = num_reversed * 10 + num % 10 = 43 * 10 + 12 % 10 = 432
. That is the last 3 reversed digits of1234
. Then we also updatenum = num / 10 = 12 / 10 = 1
.On the 4th iteration,
num_reversed = num_reversed * 10 + num % 10 = 432 * 10 + 1 % 10 = 4321
. That is our full reversed number. Then we also updatenum = num / 10 = 1 / 10 = 0
. End of thewhile
loop.The reversed number
4321
is returned from the function.
To process a possible i32
overflow scenario, we also have num_reversed.abs() > i32::MAX / 10
check, which, if satisfied, would stop the flow and return 0
from the function. Without this check num_reversed * 10
multiplication could go outside i32::MAX
(or i32::MIN
) range, so this condition checks beforehand if the overflow would happen or not.