Reverse Integer en LeetCode: solución en Python

Continuando con los problemas de LeetCode toca el turno del problema de "voltear" un número entero, pero con la restricción de que dicho número debe ser un entero de 32 bits con signo. Esta restricción tan específica me hizo sospechar que había truco, así que ni siquiera intente el enfoque de convertir a string y luego voltear esa string y pasé directo al enfoque de la división modular:


class Solution:
    def reverse(self, x: int) -> int:
        aux = abs(x)
        # mitad positiva, mitad negativa
        limit = 2**32 / 2

        if aux > limit:
            return 0

        negative = x < 0
        result = 0

        while aux > 0:
            digit = aux % 10
            aux //= 10
            result = result * 10 + digit
        
        if result > limit:
            return 0

        if negative and 0 != result:
            result *= -1
        
        return result

Aquí tomé en cuenta lo del número entro con signo, entonces tomé el valor de 2^32 y lo dividí entre 2 para tener una parte negativa y una parte positiva, y todo funcionó maravillosamente, pero Claude siempre tiene algo que decir:

El límite real de un entero de 32 bits con signo es 2**31 - 1 para positivos y -2**31 para negativos. Tu limit está un valor por encima del límite real positivo. Hay otro detalle en tu solución: revisas if aux > limit al inicio, antes de invertir; pasa que un número grande puede revertirse a algo pequeño (ej. 1000000000 → 1), y un número dentro del límite puede revertirse a algo que desborda. Entonces esa primera validación la puedes eliminar con confianza.

Con esas observaciones hice los ajustes y voilá:


class Solution:
    def reverse(self, x: int) -> int:
        negative = x < 0
        aux = abs(x)
        result = 0
        ulimit = 2**31 - 1
        llimit = -2**31

        while aux > 0:
            digit = aux % 10
            aux //= 10
            result = result * 10 + digit
        
        if negative:
            result *= -1
        
        if llimit > result or result > ulimit:
            return 0
        
        return result
Tu solución está bien. La cantidad de dígitos de un entero de 32 bits está acotada por una constante (máximo 10 dígitos). Entonces tu solución técnicamente es O(1). O(1) significa que el tiempo de ejecución no crece con el tamaño del input — es constante. En este caso, no importa qué entero de 32 bits te den, siempre vas a iterar máximo 10 veces en el while. El número de operaciones tiene un techo fijo. No hay forma de que el input haga crecer ese número. Contrasta con el problema anterior de zigzag: ahí sí el string puede ser arbitrariamente largo, y tu loop crece proporcionalmente — eso es O(n).

Finalmente pregunté por el enfoque óptimo o el algoritmo específico para resolver este problema.

Lo abordaste correctamente desde el inicio. El enfoque estándar para este problema es
exactamente el que tienes: extraer dígitos con módulo y división entera, reconstruir el número, validar límites. No hay un algoritmo más sofisticado esperado aquí. La única alternativa común es convertir a string, invertirlo, y reconvertir a int — pero eso es menos eficiente y menos elegante que lo que hiciste.

!No'mbre a veces soy una cosa pero bárbara¡

Problema anterior | Problema siguiente

Comentarios