题目描述

✅ 9. 回文数

image-20260928202932979

image-20260928202932980

题意分析

判断整数的十进制表示从左到右和从右到左是否相同。负号也是表示的一部分,因此负数不是回文数;0 和所有非负的一位数都是回文数。

非零整数不保留前导零,所以末位是零的正数不可能是回文。题目进阶要求不转成字符串,可以直接操作数字位;只需返回是否回文,不必得到整个数字的反转结果。

解法:反转后一半数字

核心思路

[!blue]

回文只要求前半段与反转后的后半段一致,中间一位可以不参与比较。因此保留 x 作为尚未处理的高位,用 reverted 从零开始保存已经取走的低位的逆序。每轮通过 x % 10 取出末位,用 reverted * 10 + x % 10 将它接到反转部分,再通过 x /= 10 删除原末位。

先排除负数和非零尾零数后,原末位不是零,反转部分不会因前导零丢失位数。在取走不足一半数位时,剩余 x 的位数更多,必有 x > reverted,应继续处理。反转部分追上或超过剩余部分后,才达到需要比较中间位置的阶段,循环条件因而使用 x > reverted。

若原数有偶数位且是回文,两半相等时恰好停止,检查 x == reverted 即可。若有奇数位,反转部分会多包含一个中间数字,它处在 reverted 的个位;去掉这一位后,用 x == reverted / 10 比较两侧。中间数字本来就与自身对称,不影响回文性。

非回文的偶数位数在两半位数相同时可能仍有 x > reverted,这时会多取一位,但最后两个相等条件都不会通过:反转部分的位数已经超过能够配对的范围。算法不需要预先知道位数或奇偶,只需同时检查这两个结束条件。

只反转约一半数位,避免构造可能超出整数范围的完整反转值。0 不进入循环,两部分仍为零,最终自然返回 true。

解题步骤

  1. 若 x < 0,或 x 非零且末位为零,返回 false。
  2. 初始化 reverted = 0,当 x > reverted 时,取出 x 末位追加到 reverted,再删除 x 末位。
  3. 循环结束后,若 x == reverted 或 x == reverted / 10,返回 true;否则返回 false。

代码实现

class Solution {
    public boolean isPalindrome(int x) {
        if (x < 0 || (x % 10 == 0 && x != 0)) {
            return false;
        }

        int reverted = 0;

        while (x > reverted) {
            reverted = reverted * 10 + x % 10;
            x /= 10;
        }

        // 偶数位直接比较两半,奇数位去掉反转部分的中间位。
        return x == reverted || x == reverted / 10;
    }
}
func isPalindrome(x int) bool {
    if x < 0 || (x%10 == 0 && x != 0) {
        return false
    }

    reverted := 0
    for x > reverted {
        reverted = reverted*10 + x%10
        x /= 10
    }
    // 偶数位直接比较两半,奇数位去掉反转部分的中间位。
    return x == reverted || x == reverted/10
}

复杂度分析

  • 时间复杂度:$O(d)$,d 为十进制位数,每轮移动一位,实际只处理约一半数位。
  • 空间复杂度:$O(1)$,只保存剩余高位和已经反转的低位。

关键点总结

[!green]

  • 排除非零尾零数,保证逆序部分不会因为前导零而丢失位数。
  • 将末位逐个搬到反转部分,用两侧大小关系决定何时停止。
  • 偶数位直接比较两半,奇数位先丢掉反转部分末尾的中间位。
  • 完整反转不是判定所必需的信息,保留一半即可避免其溢出问题。

易错点总结

[!yellow]

  • 将所有末位为零的数都判为失败,会错误排除 0,尾零特判必须同时要求非零。
  • 不排除非零尾零数,反转部分会丢掉前导零,可能使奇数位的比较条件错误成立。
  • 使用 x >= reverted 作为循环条件,会在偶数位两半已经相等时继续拆位;输入零还会一直停在零而无法结束。
  • 只保留一种结束比较,无法同时覆盖奇数位和偶数位的回文数。
  • 为负数取绝对值再判断,忽略了负号导致其本身不是回文的题意。

相似题目

题目 难度 关联与区别
7. 整数反转 中等 反转数字的取余与除法可复用,本题反转一半即可,避免完整反转的溢出风险。
125. 验证回文串 简单 同样比较正反两端,本题直接操作数字位,原题还需过滤字符并忽略大小写。
转载与许可
作者
链接 https://hgnulb.github.io/blog/2026/76476487
许可 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!