#9 数学模拟 简单

回文数

在 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 时正好过半,停止。

🧠 变量语义(先读这三句再编码)

变量类型语义(三句法)
revertedint定义:数字后半部分反转后的值
维护:每轮把 x 的当前末位接到 reverted 末尾
更新:reverted = reverted * 10 + x % 10
xint定义:尚未处理的前半部分
维护:每轮去掉一个末位
更新:x //= 10,当 x ≤ reverted 时循环停止(已过半)

⌨️ 落码步骤

1. 特判:x < 0(x % 10 == 0 且 x != 0) 直接返回 false

2. 循环 while x > revertedreverted = reverted*10 + x%10x //= 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