LeetCode 每日一题坚持到第 9 题,今天这道回文数,我打算认真写一次。这题在 LeetCode 上是 easy 难度,但真要说“透彻掌握”,大部分人其实没有。回文数的定义小学就学过,从左往右读和从右往左读一样,比如 121、1221、12321;可一旦把判断方式限定在“不能转字符串、不能开数组、只靠整数运算”,思路就完全不一样了。
这篇文章我会给你两套 Python 解法:完整反转法和反转后半部分法。前者好理解,适合新手把算法逻辑跑通;后者是 LeetCode 官方也认可的精简方案,能少算约一半位数,也是面试官更愿意看到的思路。不管你是刚开始刷题的新手,还是准备把基础题整理成笔记的老手,这篇都值得收藏。我会把两套代码的原理、运行过程、边界用例和本地自测方法全部拆开讲,你照着敲一遍就能直接提交。
先说一个我自己的观点:回文数这题,很多答案只是扔出一行 str(x) == str(x)[::-1],看起来很优雅,但这恰恰是刷题里最危险的“假会”。本文最后会解释为什么建议你不要停在字符串法上。
1. 回文数这题到底在考什么
1.1 题目回顾:先别急着写代码
LeetCode 第 9 题要求你写一个函数,判断一个整数 x 是否是回文数。它给的例子有三个:121 是,-121 不是,10 不是。
这三个例子已经把核心考点暴露得很清楚了。第一,负数为什么不是回文数?因为负号在数字最前面,如果从右往左读,负号会跑到末尾,比如 -121 反过来是 121-,这显然不相等。第二,为什么 10 不是?因为数字的末位是 0,两个方向读会出现“01”和“10”的差异。第三,题目没有说“禁止转换字符串”,这是一个隐藏考点,真正有经验的面试官会追问你能不能不用额外空间完成。
这道题虽然标着 easy,但它并没有那么简单。它考察的不是你能不能判断一个字符串是否对称,而是你能不能理解“十进制整数的位数分离”和“累加反转”这两个基础操作。这两个操作日后做整数反转、回文链表、最长回文子串时都会反复用到。
1.2 第一直觉:转字符串法为什么不够
顺着前面的疑问,先来说说那个一行字符串解法:
python复制def isPalindrome(self, x: int) -> bool:
return str(x) == str(x)[::-1]
这行代码能通过测试,但它有三个问题。第一,它把整数转成字符串,产生了一份额外的字符数组,空间复杂度是 O(n),而用纯数字判断可以做到 O(1)。第二,它没有训练到反转类算法的基本功。LeetCode 第 7 题“整数反转”和第 9 题往往是连着刷的,如果你只会转字符串,后面遇到不能转字符串的题目还是会卡住。第三,字符串反转的思维无法迁移。以后你遇到回文链表,没法把链表的每个值转成一个字符串再判断,你必须学会“找中点、反转后半段”这种对称操作的思路。
所以本文下面讲的两个数字解法,不是炫技,而是帮你建立一套后续能复用的思维模型。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 两种解法的整体设计思路
2.1 核心思维:把数字“倒过来”再比较
判断回文数最天然的思路是:把一个数字倒过来,看倒过来的结果是否和原来相等。121 倒过来还是 121,所以是回文数;123 倒过来是 321,不是回文数。
问题在于,怎样用纯数学方式“倒”一个整数。这里用到的技术,是所有整数操作题里最重要的一个小套路:每次取当前数字的末位,然后把它拼接到结果后面。
单独看一个例子,如果 x = 123,想要反转成 321,过程是这样:
- 第 1 步,取 123 的末位 3;
- 第 2 步,把 123 去掉末位变成 12;
- 第 3 步,再取 12 的末位 2;
- 第 4 步,把 12 变成 1;
- 第 5 步,取 1 的末位 1;
- 第 6 步,把 1 变成 0,循环结束。
把这个过程翻译成代码公式,就是下面两行的反复执行:
python复制reversed_num = reversed_num * 10 + x % 10 # 取出最后一位并追加到结果末尾
x //= 10 # 去掉已经处理过的最后一位
用个生活化类比:反转数字就像倒积木。你面前有一列积木,最上面那块最容易拿。每次拿掉最上面那块,放到另一个空盒子里;第二次拿到的积木放在第一次拿到的上面。等原来那列积木全部拿完,新盒子里积木的顺序就和原来完全相反了。x % 10 是“拿最上面那块”,x //= 10 是“把这块从原队列里移除”,reversed_num * 10 + 新块 是“把新块放到新盒子的最上面”。
2.2 完整反转法和反转后半部分法,差异在哪
有了上面的反转公式,题目自然出现两个分支。
第一种是完整反转法。把整个数字全部反转,得到一个新整数,再拿它和原始数字比。如果是回文数,反转后的数字会等于原始数字;如果不是,就不等。
第二种是反转后半部分法。它利用回文数的对称性:只要后半部分反转后和前半部分相等,就说明整体是回文。比如 1221,前半部分是 12,后半部分 21 反转后是 12,两边对上,是回文;比如 12321,前半部分是 12,中间位是 3,后半部分 21 反转后去掉中间位还是 12,也对上。
第二种方法在计算量上有天然优势。完整反转法
