LeetCode 第 9 题,回文数(Palindrome Number)。这题我每次带人入门刷题都会拎出来讲一遍,因为它太适合用来理解“整数处理”和“边界条件”了。很多新手拿到题目第一反应是转字符串再反转,这当然能过,但今天想聊的是更贴合题目本意的两种数字解法:完整反转法和反转后半部分法。如果你希望以后做整数类题目时不只靠拼 API,或者面试时被问到“能不能不用字符串解决”,这篇文章应该能帮你把思路彻底理清楚。
题目本身不难,难的是把每个细节都处理干净。比如负数算不算回文?末尾是 0 的数要注意什么?反转一半的循环到底什么时候停?这些点一旦想明白,以后遇到 LeetCode 7(整数反转)、LeetCode 234(回文链表)这类题目,你都会觉得顺畅很多。下面我按自己实际做题时的思考过程来拆解。
1. 题目复盘:回文数到底在考什么
1.1 题目描述和样例信号
题目要求很简单:给你一个整数 x,如果 x 是一个回文整数,返回 true,否则返回 false。回文整数指的是正序(从左向右)和倒序(从右向左)读都是一样的整数,比如 121、1221、12321 都是回文数。
样例通常给这么几个:
- 输入 121,输出 true
- 输入 -121,输出 false,因为从左到右是 -121,从右到左是 121-
- 输入 10,输出 false,因为从右到左是 01,和原数不一致
这几个样例其实已经把最关键的两个边界信号放出来了。负号是一个很明显的坑,它提醒你回文判定涉及的是十进制数字序列,符号会破坏对称性。而 10 这个样例则更隐晦:它末尾带 0,反转后首位会变成 0,这在十进制整数表示里是不可能存在的,所以除了 0 本身以外,所有末尾为 0 的整数都不可能是回文数。
我在实际做题时习惯先把这些隐藏信息抽出来,再想解法。因为 LeetCode 的样例往往不止是让你验证算法正确性,还在暗示你哪些边界情况会被判 false,哪些测试用例隐藏在后台等着你漏掉。
1.2 为什么说这题本质是数学题而非字符串题
如果允许转字符串,这题一行就能写完:return str(x) == str(x)[::-1]。这个写法在 LeetCode 上能通过,代码也最简单。但你可以留意一下:很多公司面试官并不反感你用字符串法,可如果你想展示自己对整数底层运算的熟悉程度,就最好能给出不用字符串的解法。
原因在于,整数的十进制表示本身就是数字不断除以 10 取余数的过程。要判断回文,本质上是在对比“最高位数字”和“最低位数字”是否一致,然后逐层往里收缩。这种对比如果用取模 % 和整除 // 来实现,你就是在用数学运算直接操作数字,整个过程不依赖额外空间去复制字符串,也不存在字符串转换带来的隐式开销。
另外,转字符串的方案虽然简单,但在其他语言里可能会隐藏一些细节。比如负数转字符串后带负号,你需要额外判断;或者在某些语言里整数转字符串后反转会产生前导零问题。用纯数字解法,反而可以把这些语言相关的坑全部避开,逻辑是通用的。这也是我在本地用 Python 练习时始终坚持手写数字逻辑的原因。
1.3 拿到题先想清楚三类边界
做这道题我建议先理出三类边界,再开始写代码:
- 负数:只要 x 小于 0,直接 false,不需要进入后续逻辑。因为负号永远不会对称。
- 末尾为 0 且 x 不为 0:比如 10、100、1230。这类数的最高位不可能是 0,但反转后最低位会变成 0,所以不可能回文。
- 0 本身:0 是个特殊情况,它既满足负数检查,也不落入“末尾 0”的坑里,应该返回 true。
当你把这三类边界在纸上写清楚之后,整个解法的主干其实就已经清晰了,后面就是选一种反转策略去实现。很多同学一上来就写主逻辑,结果边界漏了,反复提交反复红,其实先花半分钟列边界,比多提交十次更省时间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 解法一:完整反转法,最直观的“把数字倒过来”
2.1 核心思路与第一版代码
完整反转法的思路非常直白:既然
