【每日一题】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),不需要额外空间。

总结

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

相关推荐
xiaoshiguang34 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡4 小时前
【C语言】判断回文
c语言·学习·算法
别NULL4 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇4 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
CYBEREXP20085 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
yuanbenshidiaos5 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos5 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA6 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
tianmu_sama6 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++