在问 · 算法题解

7. 整数反转

题目描述

输入一个 32 位有符号整数 x。把它的各位数字倒过来排列,符号保持不变,返回得到的整数。倒过来后开头的 0 会自然消失。

如果结果落在 [-2^31, 2^31 - 1] 之外,返回 0。

假设运行环境不能存放 64 位整数,无论有无符号。

示例 1
输入:x = 123
输出:321
示例 2
输入:x = -123
输出:-321

解释:符号保留,数字部分 123 反转为 321。

示例 3
输入:x = 120
输出:21

解释:反转得到 021,前导零去掉后是 21。

数据范围

  • -2^31 <= x <= 2^31 - 1

解题思路

先记下符号,只处理绝对值。每次用 x % 10 取出最低位 digit,再 x //= 10 去掉它,把 digit 接到 rev 的末尾:rev = rev * 10 + digit。关键在于溢出要在乘 10 之前判断:只有 rev <= (2^31 - 1 - digit) // 10 时,rev * 10 + digit 才不会超过上限。

为什么正确

rev 始终是已弹出数字按反序组成的数,并且始终不超过 2^31 - 1。

复杂度分析

时间 O(log|x|),即数字位数;额外空间 O(1)。

易错点

先算 rev * 10 + digit 再检查溢出,在 C++/Java 中已经溢出了,结果不可信。必须在推入之前用 (INT_MAX - digit) / 10 比较。另外 abs(-2^31) 在 32 位整数中会溢出,要先转成 64 位或分别处理。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def reverse(self, x: int) -> int:
        sign = -1 if x < 0 else 1
        x = abs(x)
        rev = 0
        while x:
            digit = x % 10
            x //= 10
            if rev > (2**31 - 1 - digit) // 10:
                return 0
            rev = rev * 10 + digit
        return sign * rev

载入编辑器,自己跑一遍 →

数学 专题的其他题目

查看 数学 全部题目 →