LeetCode #7: Reverse Integer

In this post, i will be solving the LeetCode #7: Reverse Integer problem. In my opininion, this is an easy problem but you may fall in some traps. Let's read the problem statement:

Problem Statement

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³¹, 2³¹ - 1], then return 0.

Assume the environment does not allow you to store 64-bit integers (signed or unsigned).

Examples:
  • Input: x = 123
    Output: 321
  • Input: x = -123
    Output: -321
  • Input: x = 120
    Output: 21

My Approach

Python crackheads might say "just convert the number to a string and reverse it", but this is a horrible approach, because you're not thinking mathematically about the problem. In fact, most of the solutions i found in the leetcode solutions are using this way. It is not wrong, it may be faster even, but i just don't like it. Let's think about how a "number reversal" works. First of all, let's think about how our number system works. Most of us, unless you're a computer that uses binary, use a base-10 number system. This means that each digit in a number represents a power of 10. For example, a number N can be represented as: \[N = \sum_{i=1}^m r^{i-1}d_{i-1} + \sum_{j=-1}^n r^j d_j\] where r is the base (10 in our case), and d_i represents each digit. The first sum is for the integer part of the number, and the second sum is for the decimal part. This might look confusing, but it's actually a very simple concept. Let's take an example: \[N = 123\] This can be represented as: \[123 = 1*10^2 + 2*10^1 + 3*10^0\] Yeah, it is really that trivial. But this is a useful concept to understand how numbers work in base 10. Since we are working with base 10 integers, we don't need the second sum: \[N = \sum_{i=1}^m 10^{i-1}d_{i-1}\] Now, let's think about how we can reverse this number. If we want to reverse the number, we need to reverse the order of the digits. For example, the number 123 would become 321. Let's see how it would look like: \[N = 1*10^2 + 2*10^1 + 3*10^0\] If we want to reverse the number, we need to reverse the order of the exponents. \[N = 1*10^0 + 2*10^1 + 3*10^2\] we can simplify this and write it in an iterative way in pseudocode:

def reverse(x: int) -> int:
result = 0
while x > 0:
    result = result * 10 + x % 10
    x //= 10
return result
                    
Let's "run" this. Let's take the number 123 and debug this:
Step x x % 10 result * 10 result
Initial 123 - - 0
1 12 3 0 3
2 1 2 30 32
3 0 1 320 321
Tada! We have our reversed number. But that only works for positive numbers. What if we have a negative number? We can give it a small twist and check the sign of it. If it is negative, we can just multiply the result by -1 at the end. But we have to be careful with the overflow. This part is just a simple check. We finished the problem.

def reverse(x: int) -> int:
    # Handle negative numbers by working with positive values
    is_negative = x < 0
    x = abs(x)
    
    result = 0
    while x > 0:
        # Check for potential overflow before adding new digit
        if result > (2**31 - 1) // 10:
            return 0
            
        digit = x % 10
        result = result * 10 + digit
        x //= 10
    
    # Apply sign and final overflow check
    result = -result if is_negative else result
    if result < -2**31 or result > 2**31 - 1:
        return 0
        
    return result

Conclusion

A lot of developers would just parse the number to a string and reverse it with normal string operations, but you should always try to think mathematically about the problem. After all, we are nerds.