最直接的方法是字符串翻转判断回文,即用str(x)[::-1],但需先处理负数(直接返回False)并确保输入为非负整数;数学法虽避免类型转换,但需防溢出、处理边界及前导零,且仅在特定约束下必要。

字符串翻转判断回文最直接,但要注意类型转换
Python 里用 str(x)[::-1] 判断回文数,本质是把数字转成字符串再翻转,写起来快,读起来也直观。但得先确认输入是整数且非负——负数带负号,"-121" 翻转后是 "121-",肯定不等,直接返回 False 就行,不用额外处理符号逻辑。
常见错误是忘了类型转换:x[::-1] 会报 TypeError: 'int' object is not subscriptable;还有人写 str(x).reverse(),但 str 没有 reverse() 方法(那是 list 的)。
- 只对非负整数做字符串翻转比较,负数一律不是回文
- 别用
.reverse(),字符串不可变,只能用切片[::-1] - 如果原始输入可能是字符串(比如从 API 接收的 "121"),先
strip()去空格,再判空或数字格式
数学取余反转适合避免字符串开销,但边界容易溢出
纯数学法靠循环取余、构造反转数,比如对 1221:每次取 x % 10 得末位,加到新数 rev = rev * 10 + digit 上。好处是不依赖字符串,适合嵌入式或内存敏感场景;坏处是可能整数溢出——虽然 Python 整数自动扩容,但题目常隐含“32 位有符号整数”约束(如 LeetCode 9),这时得手动检查 rev > 2**31 - 1。
更隐蔽的坑是:反转一半就够了。比如 1221,反转到 12 时原数也剩 12,可提前退出;奇数位如 12321,反转到 123 时原数剩 12,去掉末位再比——这能省一半迭代次数。
立即学习“Python免费学习笔记(深入)”;
- 每次迭代前检查
rev > (2**31 - 1) // 10,防乘 10 溢出 - 推荐反转一半:当
rev >= x时停止,再按奇偶处理(x == rev或x == rev // 10) - 注意
0结尾的数(如10),数学法反转后是1,但原数除以 10 是1,仍需单独判末位为 0 的情况(直接返回False)
性能差异其实很小,但字符串法在超长数字上更稳
对普通 int(比如 10 位以内),两种方法耗时都在纳秒级,timeit 测不出明显差别。真正拉开差距的是极端情况:比如一个 1000 位的数字字符串(虽超出 int 范围,但业务中真会出现),字符串切片 [::-1] 仍是 O(n),而数学法会因大数运算变慢,且 Python 大整数除法本身开销就高。
兼容性上,字符串法天然支持任意长度数字表示(只要内存够),数学法必须确保输入能被 Python int 安全解析——如果原始数据是 "1" + "0" * 10000,转 int 会触发短暂但可观的解析时间。
- 日常用字符串法,代码少、可读强、容错好
- 数学法只在明确要求“不转字符串”或输入确定是小整数时才值得写
- 别为了“看起来更底层”硬套数学法,Python 的字符串优化极好,
[::-1]是 C 实现的,比手写循环快得多
别忽略输入校验和特殊值
回文判断最常漏掉的是 0 和个位数。单个数字如 7、0 都是回文,但有人写数学法时初始 rev=0,循环条件设成 while x > 0,0 直接跳过,结果返回 False。字符串法也会栽在 "" 或 "+" 这类非法输入上。
另一个盲点是前导零:输入如果是 "00100",按字符串处理就是 "00100" vs "00100"[::-1] → "00100",相等;但作为数字解析后变成 100,再转字符串就只剩 "100",结果不同。所以必须明确:题目要判断的是“数字的回文性”,还是“字符串表示的回文性”。
- 个位数统一返回
True,别依赖循环逻辑覆盖 - 输入是字符串时,先
strip()再lstrip("0") or "0"处理前导零(保留全零情况) - 如果函数签名是
def isPalindrome(x: int) -> bool:,那x就是 int,不用考虑字符串输入,但得处理负数和0
事情说清了就结束。回文判断看着简单,关键在想清楚“你在判断谁的回文”——是那个数字本身,还是它此刻的字符串模样。这点没定准,后面所有优化都可能跑偏。










