回文数判断不能转字符串因违反零辅助空间要求,正确解法是只翻转后半部分再与前半比较,需处理负数、末尾0、奇数位及0和个位数等边界情况。

回文数判断为什么不能直接转字符串
因为题目明确要求「零辅助空间」,std::to_string 会分配新字符串内存,哪怕只用一次也算违规。更关键的是,转字符串后比较前后字符,本质是用 O(d) 空间(d 是位数),不满足约束。真正零空间解法必须只用几个变量,纯数学翻转或双指针模拟。
用整数翻转一半来避免溢出风险
直接翻转整个数(如 rev = rev * 10 + x % 10)可能溢出 —— 比如 INT_MAX 是 2147483647,翻转后 7463847412 超出范围。稳妥做法是只翻转后半部分,再与前半部分比较。注意边界:奇数位时,翻转部分要除以 10 再比(去掉中间那一位)。
实操要点:
- 先排除负数和末尾为 0 的数(除了 0 本身),
x 直接返回 false - 用
reversed = 0累加翻转,循环条件是x > reversed(保证只处理一半) - 循环内:
reversed = reversed * 10 + x % 10,然后x /= 10 - 退出后判断:
x == reversed || x == reversed / 10
手写取第 k 位数字的技巧(不用字符串也不翻转)
如果面试官追问“能否不翻转、不额外空间、也不用除法循环”,可以考虑按位提取,但实际更慢且不易读。核心是:位数 d 可通过 log10(x) + 1 得到(需 #include <cmath></cmath>),然后用 (x / static_cast<int>(pow(10, d - 1 - i))) % 10</int> 取第 i 位。但 pow 有浮点误差风险,static_cast<int></int> 截断可能出错;而且 log10 对 10^k 类输入不稳定(如 x=1000,log10 可能返回 3.99999)。不推荐生产使用。
立即学习“C++免费学习笔记(深入)”;
负数、0 和单数字的边界处理
回文数定义通常针对非负整数,所以负数一律不是回文。0 是回文;个位数(1~9)全是回文。这些必须显式覆盖,否则 x == reversed / 10 在 x=0 时会因整数除零或逻辑错乱出问题。
安全写法:
if (xif (x == 0) return true;-
if (x % 10 == 0) return false;(排除 10、20、100 等)
最后那个 x % 10 == 0 容易漏 —— 比如 1221 是回文,但 120 不是,而它的翻转一半逻辑会在 x == 12, reversed == 21 时误判,提前拦截更干净。
真正难的不是写对,而是想清楚「翻转一半」时循环终止条件和奇偶位的处理差异;很多人卡在 x == reversed / 10 这一行,却没意识到它只对奇数位有效,且必须确保 reversed 至少比 x 多一位才能这么除。


















