整数反转

标签: 数学

难度: Medium

给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。

如果反转后整数超过 32 位的有符号整数的范围 [−231,  231 − 1] ,就返回 0。

假设环境不允许存储 64 位整数(有符号或无符号)。

 

示例 1:

输入:x = 123
输出:321

示例 2:

输入:x = -123
输出:-321

示例 3:

输入:x = 120
输出:21

示例 4:

输入:x = 0
输出:0

 

提示:

  • -231 <= x <= 231 - 1

Submission

运行时间: 32 ms

内存: 13.5 MB

class Solution:
    def reverse(self, x: int) -> int:
        max_value = (1 << 31) - 1
        min_value = -1 << 31
        ans = 0
        while x != 0:
            if x >= 0:
                p = x % 10
            else:
                p = x % 10 - 10
            if x > 0 and ans * 10 + p > max_value:
                return 0
            if x < 0 and ans * 10 + p < min_value:
                return 0
            ans *= 10
            ans += p
            x //= 10
            if x < 0:
                x += 1
            print(p, ans, x)
        return ans


if __name__ == '__main__':
    s = Solution()
    print(s.reverse(-321))

Explain

该题解采用数学方法,通过循环不断取出 x 的最后一位数字,将其反转后累加到结果 ans 中。在每次循环中,判断反转后的结果是否溢出,若溢出则直接返回 0。具体步骤如下: 1. 初始化结果 ans 为 0 2. 当 x 不等于 0 时,进行如下操作: a. 取出 x 的最后一位数字 p(需要判断 x 的正负) b. 判断将 p 添加到 ans 后是否会溢出 c. 将 ans 乘以 10 并加上 p d. 将 x 除以 10 3. 返回结果 ans

时间复杂度: O(n)

空间复杂度: O(1)

class Solution:
    def reverse(self, x: int) -> int:
        max_value = (1 << 31) - 1  # 32位有符号整数的最大值
        min_value = -1 << 31  # 32位有符号整数的最小值
        ans = 0  # 反转后的结果
        while x != 0:
            if x >= 0:
                p = x % 10  # 取出 x 的最后一位数字
            else:
                p = x % 10 - 10  # 若 x 为负数,需要减去10以保证 p 为负数
            if x > 0 and ans * 10 + p > max_value:  # 判断正数溢出
                return 0
            if x < 0 and ans * 10 + p < min_value:  # 判断负数溢出
                return 0
            ans *= 10  # 将 ans 乘以 10
            ans += p  # 将 p 加到 ans 上
            x //= 10  # 将 x 除以 10
            if x < 0:
                x += 1  # 若 x 为负数,需要加 1 以保证除法结果向上取整
            print(p, ans, x)  # 调试输出
        return ans


if __name__ == '__main__':
    s = Solution()
    print(s.reverse(-321))

Explore

在Python中,负数取余操作结果是非负的。例如,-321 % 10 结果是1,而不是-1。为了在整数反转中保持数字的符号,需要对取余后的结果进行调整。当 x 是负数时,需要将取余结果调整为负,因此计算 -321 % 10 后再减去10,使得结果变成-9,这样能保证反转的数字是负数的正确表达。

在Python中,整数除法(//)向下取整。对于负数,这会导致结果更负。例如,-321 // 10 的结果是-33,而非-32。为了确保结果正确地向0靠拢,需要在计算除法后对结果进行调整。当 x 为负数时,除以10后再加上1,可以抵消向下取整的偏差,使得整数反转逻辑保持一致。

是的,`print(p, ans, x)`是用于调试过程中跟踪变量值的变化,帮助理解和发现代码中的错误。在实际提交到LeetCode平台时,应该删除这行代码。因为调试输出可能会影响代码运行效率,且LeetCode的提交环境并不期望或需要输出调试信息。

是的,这两个条件已经覆盖了所有可能的溢出情况。`ans * 10 + p > max_value`检查正数溢出,`ans * 10 + p < min_value`检查负数溢出。这些条件确保在整数反转过程中,如果结果超过了32位有符号整数的范围,函数会及时返回0,避免错误或未定义的行为。

在确定最大值`max_value`和最小值`min_value`时,需要根据目标平台的整数存储规范选择正确的值。对于32位有符号整数,最大值是2^31 - 1,最小值是-2^31。在Python中,可以通过计算`(1 << 31) - 1`和`-1 << 31`来得到这些值。这样的计算是基于位操作,确保根据位数直接获得正确的极限值。