Generated by Codex with GPT-5

Quick facts

What the problem is really asking

Given a signed 32-bit integer, reverse its decimal digits.

Examples:

  • 123 becomes 321
  • -123 becomes -321
  • 120 becomes 21

The catch is that the answer must still fit inside the signed 32-bit range:

  • minimum: -2^31
  • maximum: 2^31 - 1

If the reversed number falls outside that range, the function must return 0.

So the real problem is not just digit reversal. It is digit reversal with strict overflow handling.

The key insight

The cleanest solution builds the reversed number one digit at a time.

At each step:

  • remove the last digit from the current number
  • append that digit to the end of the answer being built

That is the same as repeatedly doing:

  • digit = remaining_value % 10
  • remaining_value //= 10
  • reversed_value = reversed_value * 10 + digit

The only tricky part is overflow.

Before appending a new digit, the algorithm checks whether multiplying the current answer by 10 and adding the next digit would exceed the allowed 32-bit limit.

How to derive the optimal solution

The most direct first idea is to convert the integer to a string, reverse the characters, and parse it back.

That works in Python, but it hides the real constraint and uses extra space proportional to the number of digits.

The better way is to work numerically.

Start by separating the sign:

  • remember whether the input is negative
  • work with the absolute value while reversing digits
  • restore the sign at the end

Now focus on the positive magnitude.

Each loop iteration peels off one trailing digit and pushes it into the answer:

  • 1234 becomes 123 and digit 4
  • answer 0 becomes 4
  • then 123 becomes 12 and digit 3
  • answer 4 becomes 43

That gives linear work in the number of digits and constant extra space.

The overflow rule can also be derived cleanly.

Suppose the maximum allowed magnitude is limit. Before doing:

reversed_value = reversed_value * 10 + digit

the algorithm must ensure the new value stays at most limit.

That means:

  • if reversed_value > limit // 10, the next multiplication already overflows
  • if reversed_value == limit // 10, then the next digit must be at most limit % 10

For this problem, the limit depends on the sign:

  • positive answers can be at most 2147483647
  • negative answers can have magnitude up to 2147483648

That is why it is convenient to reverse the absolute value and choose the correct bound up front.

Best approaches

  • String reversal: simple, but it uses extra space and avoids the core overflow logic.
  • Arithmetic digit extraction: O(d) time and O(1) extra space, where d is the number of digits. This is the best answer for interviews and production-quality reasoning.

Why the arithmetic solution works

The loop maintains a simple invariant:

reversed_value is always the reverse of the digits that have already been removed from remaining_value.

When one more digit is removed from the right side of remaining_value, appending it to the right side of reversed_value preserves that invariant.

Because the algorithm checks overflow before each append, it never produces an out-of-range intermediate result.

Once all digits are consumed, reversed_value is the fully reversed magnitude. Reapplying the original sign gives the final answer.

Python solution

from typing import Optional


class Solution:
    MIN_SIGNED_32_BIT = -(2**31)
    MAX_SIGNED_32_BIT = 2**31 - 1

    def reverse(self, x: int) -> int:
        sign = -1 if x < 0 else 1
        remaining_value = abs(x)
        max_allowed_magnitude = self._max_allowed_magnitude(sign)

        reversed_magnitude = self._reverse_magnitude(
            value=remaining_value,
            max_allowed_magnitude=max_allowed_magnitude,
        )
        if reversed_magnitude is None:
            return 0

        return sign * reversed_magnitude

    @classmethod
    def _max_allowed_magnitude(cls, sign: int) -> int:
        if sign > 0:
            return cls.MAX_SIGNED_32_BIT
        return abs(cls.MIN_SIGNED_32_BIT)

    def _reverse_magnitude(
        self,
        value: int,
        max_allowed_magnitude: int,
    ) -> Optional[int]:
        reversed_value = 0

        while value > 0:
            value, digit = divmod(value, 10)

            # Check the next append before performing it so the result always
            # stays within the signed 32-bit constraint.
            if self._would_overflow(
                current_value=reversed_value,
                next_digit=digit,
                max_allowed_magnitude=max_allowed_magnitude,
            ):
                return None

            reversed_value = reversed_value * 10 + digit

        return reversed_value

    @staticmethod
    def _would_overflow(
        current_value: int,
        next_digit: int,
        max_allowed_magnitude: int,
    ) -> bool:
        return (
            current_value > max_allowed_magnitude // 10
            or (
                current_value == max_allowed_magnitude // 10
                and next_digit > max_allowed_magnitude % 10
            )
        )