DEV Community

AussieCoder
AussieCoder

Posted on

LeetCode Solution: 7. Reverse Integer

Cracking LeetCode 7: How to Reverse an Integer Safely (and Why It's Tricky!)

Hey awesome developers! 👋 Welcome back to another exciting LeetCode breakdown with aaradhyanegi009. Today, we're diving into a classic problem that seems simple on the surface but hides a crucial twist: Reversing an Integer. It's a fantastic exercise for understanding integer manipulation and, more importantly, how to deal with the dreaded "integer overflow."

Let's get started!


🚀 Problem Explanation: Reverse Integer (LeetCode #7)

You're given a signed 32-bit integer, let's call it x. Your task is to return this integer with its digits reversed. Sounds easy, right?

Here's the catch:

  1. Signed 32-bit integer range: This means x can be anywhere from -2,147,483,648 to 2,147,483,647.
  2. Overflow Check: If the reversed version of x goes outside this 32-bit signed integer range, you must return 0.
  3. No 64-bit integers (for final result): You're assumed not to be able to store 64-bit integers. This implies that your final return value should fit within a 32-bit integer, and you need clever ways to detect overflow without relying on a larger type for the final result.

Let's look at some examples:

  • Example 1: x = 123

    • Output: 321 (Simple reversal)
  • Example 2: x = -123

    • Output: -321 (Negative sign needs to be preserved)
  • Example 3: x = 120

    • Output: 21 (Trailing zeros become leading zeros and disappear)

💡 Intuition: The "Aha!" Moment

When you think about reversing digits, two main strategies often come to mind:

  1. Mathematical Approach: Repeatedly extract the last digit (x % 10), build the reversed number (reversed = reversed * 10 + digit), and truncate x (x /= 10). This is efficient but makes overflow checking a bit more intricate, as you need to check before each multiplication.

  2. String Conversion Approach: Convert the number to a string, reverse the string, and then convert it back to a number. This often feels more intuitive for reversing sequences and can simplify overflow detection, as you perform the reversal first and then check the final value.

For this problem, especially given the "no 64-bit integers" constraint (which is often interpreted as "don't return a 64-bit integer, but you might use it temporarily for safety checks"), the string conversion approach combined with careful type handling provides a very robust and readable solution.

The "aha!" here is realizing that a long long (which is typically 64-bit) can be your best friend for intermediate calculations and overflow checks, even if your final answer must fit in an int (32-bit). You build the potentially overflowing number in a long long, then compare it against the INT_MAX and INT_MIN boundaries before casting it back to an int. This way, you catch overflows safely.


📋 Approach: Step-by-Step Logic

Our chosen approach leverages string manipulation for the reversal and long long for safe overflow detection.

  1. Preserve the Sign and Get Absolute Value:

    • First, we need to know if the original x was negative. We'll store its sign and work with its absolute value. This simplifies the reversal process, as we don't have to worry about the negative sign until the very end.
    • We store x in a long long variable (val) right away to prevent any potential overflow issues if x itself is INT_MIN (which behaves strangely with abs() in some contexts).
  2. Convert to String:

    • Convert the absolute value of val into a string. This allows us to easily manipulate its digits. For x = 123, num becomes "123". For x = -123, num becomes "123".
  3. Reverse the String:

    • Use a standard library function (like std::reverse in C++) to reverse the num string. "123" becomes "321", and "12" becomes "21".
  4. Convert Back to Number (Safely!):

    • Convert the reversed string back into a numerical type. Here's where long long shines! We convert it into a long long (res) using stoll() (string to long long). This lets res temporarily hold values larger than INT_MAX or smaller than INT_MIN without crashing, so we can then check them.
  5. Reapply the Original Sign:

    • If the original x was negative (checked by x < 0), multiply our res by -1 to restore its negative sign.
  6. Perform Overflow Check:

    • Now that we have the final res as a long long, we compare it against the INT_MAX (2,147,483,647) and INT_MIN (-2,147,483,648) limits.
    • If res is greater than INT_MAX or less than INT_MIN, it means the reversed integer overflows a 32-bit signed integer. In this case, as per the problem, we return 0.
  7. Return the Result:

    • If no overflow occurred, we know res perfectly fits into a 32-bit integer. We cast res to an int and return it.

This approach gracefully handles negative numbers, trailing zeros, and the all-important overflow condition, while respecting the underlying 32-bit integer limits for the final result.


💻 Code

Here's the C++ implementation following our approach:

#include <string>    // Required for std::string, to_string, stoll
#include <algorithm> // Required for std::reverse
#include <limits>    // Required for INT_MAX, INT_MIN (or just use <climits>)

class Solution {
public:
    int reverse(int x) {
        // Use INT_MAX and INT_MIN from <limits> for clarity
        // Or directly use numeric_limits<int>::max() / min()
        int max_V = std::numeric_limits<int>::max();
        int min_V = std::numeric_limits<int>::min();

        // Use long long to safely store x initially. 
        // This is crucial for handling INT_MIN correctly with abs() if used directly.
        long long val = x; 

        // 1. Convert absolute value of the number to a string
        // abs() ensures we work with positive digits first
        std::string num = std::to_string(std::abs(val)); 

        // 2. Reverse the string
        std::reverse(num.begin(), num.end());

        // 3. Convert the reversed string back to a long long.
        // This allows us to temporarily hold a value that might exceed int limits
        // before we perform the overflow check.
        long long res = std::stoll(num);

        // 4. Reapply the original sign
        if (x < 0) {
            res *= -1;
        }

        // 5. Check for 32-bit integer overflow/underflow
        if (res > max_V || res < min_V) {
            return 0; // Return 0 if the reversed integer is out of range
        }

        // 6. If no overflow, cast the long long result back to int and return
        return static_cast<int>(res);
    }
};
Enter fullscreen mode Exit fullscreen mode

⏱️ Time & Space Complexity Analysis

Let's break down the efficiency of this solution:

Time Complexity: O(log10(x)) or O(1)

  • std::to_string(std::abs(val)): The time taken to convert an integer to a string is proportional to the number of digits in the integer. If D is the number of digits in x, this is O(D).
  • std::reverse(num.begin(), num.end()): Reversing a string of length D takes O(D) time.
  • std::stoll(num): Converting a string back to a long long also takes time proportional to the number of digits, O(D).

For a 32-bit integer, the maximum number of digits is 10 (e.g., 2,147,483,647). Since D is effectively a constant for fixed-size integers, the operations are constant time relative to the number of digits. Therefore, the overall time complexity is often considered O(1) for practical purposes in competitive programming context where the input integer's size is fixed (32-bit). If we consider x to be arbitrarily large, it would be O(log10(x)).

Space Complexity: O(log10(x)) or O(1)

  • std::string num: We create a string to store the digits of x. The length of this string is D, the number of digits in x.

Similar to time complexity, for a 32-bit integer, D is at most 10, making the space usage effectively constant. Thus, the space complexity is often considered O(1). If x were arbitrarily large, it would be O(log10(x)).


✨ Key Takeaways

  1. String Power: Don't underestimate the power of string conversions for digit-based problems. They can simplify complex logic like reversal and often offer good readability.
  2. Overflow is King: In integer problems, handling overflow is paramount. Always consider the data type limits (INT_MAX, INT_MIN) and how your operations might exceed them.
  3. Temporary long long (or Wider Types): Even if the problem constraints state that the final result must fit into a smaller type (like int), you can often use a wider type (long long) for intermediate calculations or for checking potential overflow before clamping the final result. This is a common and safe pattern.
  4. Edge Cases: Always test with edge cases like negative numbers (-123), numbers ending in zero (120), and boundary values (INT_MAX, INT_MIN, or their reversed versions if they exist).

This problem serves as an excellent reminder that even seemingly simple tasks can have hidden complexities, pushing us to write more robust and error-resistant code. Keep coding, keep learning!


Authored by aaradhyanegi009 | Published on 2026-05-18 06:29:57

Top comments (0)