【每日一题】LeetCode - 判断回文数

今天我们来看一道经典的回文数题目,给定一个整数 x ,判断它是否是回文整数。如果 x 是一个回文数,则返回 true,否则返回 false
回文数 是指从左往右读和从右往左读都相同的整数。例如,121 是回文,而 123 不是。

示例

  • 示例 1

    输入:x = 121

    输出:true

    解释:121 从左往右和从右往左都相同,因此是回文数。

  • 示例 2

    输入:x = -121

    输出:false

    解释:从左向右读为 -121,从右向左读为 121-。负号出现在末尾,因此不是回文数。

  • 示例 3

    输入:x = 10

    输出:false

    解释:从右向左读为 01,与原数不相同。


思路解析

本题的核心是判断一个数字在正序和倒序上是否一致。一般地,可以想到两种解决方案:

  1. 字符串法:将整数转为字符串,判断字符串是否为回文。虽然这种方法简单直观,但它占用额外空间,不是最优解。

  2. 数学反转法:直接在数字层面反转整数的一半,再与另一半比较。这个方法通过操作数字本身,不使用额外空间,效率较高且实现优雅。

接下来,我们基于数学反转法优化解答。


优化的数学反转解法

在反转整数时,不需要整个数字的倒序,只需反转其一半。在反转过程中,如果反转后的数字与剩余的部分一致,说明该数字是回文。

优化步骤

  1. 负数直接排除:负数不可能是回文,因为其倒序会使负号出现在末尾。

  2. 非零且尾数为零的数字也可排除 :如 10100。若一个数的末尾是 0,且它不是 0 本身,它就不可能是回文。

  3. 反转数字的一半

    • 每次将 x 的最后一位拼接到 reversedHalf 后面,同时将 x 缩短一位,直到 x 的长度小于或等于 reversedHalf
    • 如果数字的长度是偶数,则反转后的 reversedHalfx 应相等。
    • 如果数字的长度是奇数,则可以忽略 reversedHalf 的中间位(即 reversedHalf / 10),此时两者也应相等。

代码实现

cpp 复制代码
class Solution {
public:
    bool isPalindrome(int x) {
        // 负数或非零尾数为0的数无法成为回文数
        if (x < 0 || (x % 10 == 0 && x != 0)) return false;

        int reversedHalf = 0;
        while (x > reversedHalf) {
            reversedHalf = reversedHalf * 10 + x % 10;
            x /= 10;
        }

        // 判断两种情况:
        // 1. x == reversedHalf 表示偶数长度,反转完全相同
        // 2. x == reversedHalf / 10 表示奇数长度,忽略中间一位
        return x == reversedHalf || x == reversedHalf / 10;
    }
};

代码详解

  • x < 0 || (x % 10 == 0 && x != 0):这是排除负数和非零尾数为零的情况,这些数不可能是回文。

  • while (x > reversedHalf):每次将 x 的最后一位加到 reversedHalf 后面,缩短 x。这个过程在 x 的长度超过 reversedHalf 的长度时停止。

  • return x == reversedHalf || x == reversedHalf / 10:在循环结束后,有两种可能:

    • 若数字长度为偶数,则 x == reversedHalf
    • 若数字长度为奇数,则 x == reversedHalf / 10(忽略中间一位,见下面的例子)。

举例分析

x = 12321 为例,展示代码的运行过程:

  • 初始化x = 12321reversedHalf = 0
  • 第一轮循环
    • reversedHalf = reversedHalf * 10 + x % 10 = 0 * 10 + 1 = 1
    • x = x / 10 = 1232
  • 第二轮循环
    • reversedHalf = 1 * 10 + 2 = 12
    • x = 123
  • 第三轮循环
    • reversedHalf = 12 * 10 + 3 = 123
    • x = 12

循环结束后,reversedHalf123x12,可以看到 reversedHalf / 10 = 12,即 x == reversedHalf / 10 成立,因此 12321 是回文数。


复杂度分析

  • 时间复杂度:O(log₁₀(n)),因为我们只遍历数字的一半。
  • 空间复杂度:O(1),不需要额外空间。

总结

这个方法不仅优化了空间使用,还保证了执行效率,是一种优雅的实现方案。通过这种方式,我们可以轻松判断整数是否为回文。该解法具有优秀的时间和空间复杂度,是回文数问题的最佳解法之一。

相关推荐
不想编程小谭18 分钟前
力扣LeetCode: 2506 统计相似字符串对的数目
c++·算法·leetcode
水蓝烟雨35 分钟前
[HOT 100] 2187. 完成旅途的最少时间
算法·hot 100
曼巴UE51 小时前
UE5.3 C++ TArray系列(一)
开发语言·c++·ue5
01_1 小时前
力扣hot100——LRU缓存(面试高频考题)
leetcode·缓存·面试·lru
菜鸟一枚在这2 小时前
深度解析建造者模式:复杂对象构建的优雅之道
java·开发语言·算法
gyeolhada2 小时前
2025蓝桥杯JAVA编程题练习Day5
java·数据结构·算法·蓝桥杯
阿巴~阿巴~2 小时前
多源 BFS 算法详解:从原理到实现,高效解决多源最短路问题
开发语言·数据结构·c++·算法·宽度优先
给bug两拳2 小时前
Day9 25/2/22 SAT
算法
CoderCodingNo3 小时前
【GESP】C++二级真题 luogu-b3924, [GESP202312 二级] 小杨的H字矩阵
java·c++·矩阵
_Itachi__3 小时前
LeetCode 热题 100 73. 矩阵置零
算法·leetcode·矩阵