回文数
在 LeetCode 上查看 ↗语音讲解
开车或通勤时可听,跟着思路走一遍
速度
题目描述
给你一个整数 x,如果 x 是一个回文整数,返回 true;否则返回 false。回文数是指正序(从左向右)和倒序(从右向左)读都一样的整数。例如 121 是回文,而 123 不是。进阶:能不能把整数转为字符串来解决?
示例 1
输入:x = 121
输出:true
示例 2
输入:x = -121
输出:false(从右往左读是 121-,不是回文)
示例 3
输入:x = 10
输出:false(从右往左读是 01)
模拟答题者思考
1. 最直接:把整数转成字符串,判断是否与其反转相等——但进阶要求不借助字符串。
2. 反转整个数字再比较?可能溢出。观察到:只需反转「后半部分」,再和「前半部分」比即可。
3. 负数一定不是回文;末位是 0 且本身非 0 的数(如 10、100)也不是(首位不能是 0)。
4. 一边砍掉 x 的末位、一边拼到 reverted,当 reverted 追上或超过 x 时正好过半,停止。
变量语义(先读这三句再编码)
| 变量 | 类型 | 语义(三句法) |
|---|---|---|
reverted | int | 定义:数字后半部分反转后的值 维护:每轮把 x 的当前末位接到 reverted 末尾 更新:reverted = reverted * 10 + x % 10 |
x | int | 定义:尚未处理的前半部分 维护:每轮去掉一个末位 更新:x //= 10,当 x ≤ reverted 时循环停止(已过半) |
落码步骤
1. 特判:x < 0 或 (x % 10 == 0 且 x != 0) 直接返回 false
2. 循环 while x > reverted:reverted = reverted*10 + x%10,x //= 10
3. 偶数位:x == reverted;奇数位:中间位在 reverted 上,用 x == reverted // 10 去掉它
4. 两者任一成立即为回文
代码实现
class Solution:
def isPalindrome(self, x: int) -> bool:
# 负数,或末位为 0 但本身非 0(如 10),都不是回文
if x < 0 or (x % 10 == 0 and x != 0):
return False
reverted = 0 # 后半部分反转值
while x > reverted:
reverted = reverted * 10 + x % 10
x //= 10
# 偶数位长度 x == reverted;奇数位长度去掉中间位 reverted // 10
return x == reverted or x == reverted // 10
class Solution {
public:
bool isPalindrome(int x) {
// 负数,或末位为 0 但本身非 0,都不是回文
if (x < 0 || (x % 10 == 0 && x != 0)) return false;
int reverted = 0; // 后半部分反转值
while (x > reverted) {
reverted = reverted * 10 + x % 10;
x /= 10;
}
// 偶数位 x == reverted;奇数位去掉中间位 reverted / 10
return x == reverted || x == reverted / 10;
}
};
// 时间 O(log₁₀ n),空间 O(1)
复杂度分析
时间复杂度
O(log₁₀ n)
空间复杂度
O(1)
常见坑
负数不是回文;末位为 0 且非 0 的数(10、120)也不是,必须先特判。
只反转一半可避免整型溢出,比反转整个数字更稳。
奇数位时中间那位落在 reverted 上,比较时要用 reverted // 10 去掉。
必测边界 Case
Case 1:单个数字
x = 0 → true
Case 2:奇数位回文
x = 12321 → true(reverted=123,x=12,12==123//10)
Case 3:末位为 0
x = 10 → false