7. Reverse Integer
Description of the Problem
Given a signed 32-bit integer x, return x with its digits reversed. If reversing x causes the value to go outside the signed 32-bit integer range [-2^31, 2^31 - 1], then return 0.
Assume the environment does not allow you to store 64-bit integers (signed or unsigned).
Example 1:
Input: x = 123
Output: 321
Example 2:
Input: x = -123
Output: -321
Example 3:
Input: x = 120
Output: 21
Constraints:
-2^31 <= x <= 2^31 - 1
Solution
Explanation
Method 1: Use standard library to convert integer
Method 2: Do the Method by yourself. First perform checking of overflow/underflow. Then reverse the integer.
Checking of Overflow/Underflow
If a reverse integer overflows (or underflows), then it has at least 10 digits. (Since i32::MAX and i32::MIN has 10 digits). By contraposition, any number has less than 10 digits does not overflows (nor underflows).
To check whether a reversed full-digit integer overflows (or underflows), we can compare the number with i32::MAX or i32::MIN digit-by-digit.
Example 1: reverse of 2091748912 is 2198471902. Compare the reversed with i32::MAX digit-by-digit
2198471902
2147483647
-----------
1st digit: they are equal (i.e. 2) ==> compare next digit
2nd digit: they are equal (i.e. 1) ==> compare next digit
3nd digit: 9 > 4 ==> It overflows
Example 2: reverse of 2091748012 is 2108471902. Compare the reversed with i32::MAX digit-by-digit
2108471902
2147483647
-----------
1st digit: they are equal (i.e. 2) ==> compare next digit
2nd digit: they are equal (i.e. 1) ==> compare next digit
3nd digit: 0 < 4 ==> It is not possible to overflow
After the checking, just simply calculate the reversed value.
Code - Method 1 (Rust)
impl Solution {
pub fn reverse(n: i32) -> i32 {
let result =
if n > 0 {
n.to_string() // convert the number into String
.chars().rev() // reverse the number_string
.collect::<String>()
.parse::<i32>() // try to parse the reversed number_string
}
else{
n.to_string() // convert the number into String
.chars().skip(1) // skip 1st character i.e. minus sign
.collect::<String>() // convert it into String due to its type
.chars().rev() // reverse the number_string
.collect::<String>()
.parse::<i32>() // try to parse the reversed number_string
.map(|x| -x)
};
// Unwrap the result
return if let Ok(x) = result{
x
}
else{
0
};
}
}
Code - Method 2 (Rust)
impl Solution {
pub fn reverse(n: i32) -> i32 {
static MAX_POW : u32 = 9; // std::i32::MAX and std::i32::MIN has 10 digits
static TEN : i32 = 10;
if Solution::will_overflow_or_underflow(n){
return 0;
}
// Calculate the sum
let mut sum = 0;
let mut n = n;
while n != 0 {
sum *= 10;
sum += n % 10;
n /= 10;
}
return sum;
}
fn will_overflow_or_underflow(n : i32) -> bool {
static MAX_POW : u32 = 9;
static TEN : i32 = 10;
// if the number is not in full-digit, so is its reverse
if ( n>= 0 && n < TEN.pow(MAX_POW)) || (n < 0 && n > -TEN.pow(MAX_POW)){
return false;
}
// Otherwise, check whether the reverse will overflow
let mut is_not_overflow = true;
let mut is_continued;
for p in 0..=MAX_POW{
let digit_n = n / TEN.pow(p) % 10;
if n >= 0{
let digit_max = std::i32::MAX / TEN.pow(MAX_POW - p) % 10;
is_not_overflow = digit_n <= digit_max;
// If the digits are equal, then we have to check next digits
// Otherwise, its reverse must be smaller than std::i32::MAX
is_continued = is_not_overflow && digit_n == digit_max;
}else{
let digit_min = std::i32::MIN / TEN.pow(MAX_POW - p) % 10;
is_not_overflow = digit_n >= digit_min;
// Similarly, if the digits are equal, then we have to check next digits
// Otherwise, its reverse must be smaller than std::i32::MIN
is_continued = is_not_overflow && digit_n == digit_min;
}
if !is_continued{break;}
}
return !is_not_overflow;
}
}
Complexity - Method 2 (\(d\) is the number of digits)
Time complexity:
- \( T(n) = O(2d) \)
- Perform Overflow/Underflow checking and Calculate the reversed number
Auxiliary Space:
- \( S(n) = O(1) \)
- Extracted digits are stored in local variables