题目描述

✅ 7. 整数反转

image-20260928200923772

题意分析

将一个 32 位有符号整数的十进制数位倒过来,负数保留负号。原数末尾的零反转后成为前导零,不影响整数结果;如果反转结果超出 [-2147483648, 2147483647],返回 0。

题目不允许借助 64 位整数先算出结果再判断,因此需要在 32 位运算真正越界之前识别风险。原输入可能等于最小负整数,不能先取绝对值再处理。

解法:逐位弹出并提前判溢出

核心思路

[!blue]

用 x % 10 取出原数最低位 digit,再用 x / 10 去掉这一位。按这个顺序取出的数字正好是反转结果从高位到低位的顺序,因此每取一位,就通过 ans * 10 + digit 追加到答案末尾。

Java 和 Go 的整数除法向零截断,余数与被除数同号。负数会直接取出负的数位,累积出的 ans 也保持为负,所以正负输入可以共用一套循环,无需对最小负整数取绝对值。

追加前必须判断结果能否留在范围内。上界 2147483647 的前九位是 214748364,末位是 7:若 ans > MAX / 10,再乘十必定超界;若恰好相等,只有 digit <= 7 才安全。较小时,追加任意合法数位都不会越过上界。

下界按同样方式判断,但整数除法向零截断后 MIN / 10 = -214748364,最后允许的负数位是 -8。因此 ans < MIN / 10,或相等且 digit < -8 时,需要提前返回 0。上下界并不对称,两侧末位不能写成同一个数。

只有两项检查都通过,才执行乘十加位。每轮原数都少一位,最终 x 归零时,所有数位已反转完成。

解题步骤

  1. 初始化 ans = 0,只要 x != 0 就继续,兼容正数和负数。
  2. 先计算 digit = x % 10,再执行 x /= 10。
  3. 检查 ans 是否超过上界除以十的商,以及商相等时 digit 是否超过 7。
  4. 检查下界的对应条件,商相等时 digit 不得小于 -8。任何一侧不满足都返回 0。
  5. 安全时令 ans = ans * 10 + digit。全部数位处理完后返回 ans。

代码实现

class Solution {
    public int reverse(int x) {
        int ans = 0;

        while (x != 0) {
            int digit = x % 10;

            x /= 10;

            // 乘十加新位之前检查上界,避免先溢出后才发现。
            if (ans > Integer.MAX_VALUE / 10 || (ans == Integer.MAX_VALUE / 10 && digit > 7)) {
                return 0;
            }

            // 负数最低界的末位为负八,与正数上界不对称。
            if (ans < Integer.MIN_VALUE / 10 || (ans == Integer.MIN_VALUE / 10 && digit < -8)) {
                return 0;
            }

            ans = ans * 10 + digit;
        }

        return ans;
    }
}
const (
    maxInt32 = 1<<31 - 1
    minInt32 = -1 << 31
)

func reverse(x int) int {
    ans := 0
    for x != 0 {
        digit := x % 10
        x /= 10
        // 乘十加新位之前检查上界,避免先溢出后才发现。
        if ans > maxInt32/10 || (ans == maxInt32/10 && digit > 7) {
            return 0
        }
        // 负数最低界的末位为负八,与正数上界不对称。
        if ans < minInt32/10 || (ans == minInt32/10 && digit < -8) {
            return 0
        }
        ans = ans*10 + digit
    }
    return ans
}

复杂度分析

  • 时间复杂度:$O(d)$,d 为十进制位数,每轮处理一位。
  • 空间复杂度:$O(1)$,只使用固定数量的整数变量。

关键点总结

[!green]

  • 取原数最低位,再追加到答案末尾,自然完成数位反转。
  • 保留负数运算避免了最小负整数无法取正值的问题。
  • 用边界的商和余数拆开判断,确保危险的乘法和加法根本不会执行。

易错点总结

[!yellow]

  • 先执行 ans * 10 + digit 再判断,32 位值可能已经回绕,无法得到正确的越界结论。
  • 对最小负整数取绝对值,它的对应正值超出 32 位范围,结果仍可能是负数。
  • 把下界末位也写成 -7,混淆了正负边界的不对称性。
  • 循环写成 x > 0,会直接跳过所有负数输入。
  • 先除十再取模,会漏掉原来的最低位;先取模再缩短原数才是正确顺序。
  • Go 的 int 在某些环境是 64 位,本题仍应按明确的 32 位上下界判断,而不是按机器整数范围判断。

相似题目

题目 难度 关联与区别
9. 回文数 简单 同样从低位取数字并构造反向数,原题只反转一半即可判断回文。
8. 字符串转换整数 (atoi) 中等 同样在乘10并加入下一位前检查整数边界,原题从字符串解析数字。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/02923903
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!