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

总结

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

相关推荐
阳光_你好42 分钟前
简单介绍C++中线性代数运算库Eigen
开发语言·c++·线性代数
codists1 小时前
《算法导论(第4版)》阅读笔记:p86-p90
算法
ShineSpark1 小时前
C++面试3——const关键字的核心概念、典型场景和易错陷阱
c++·算法·面试
爱吃涮毛肚的肥肥(暂时吃不了版)4 小时前
仿腾讯会议——音频服务器部分
c++·qt·面试·职场和发展·音视频·腾讯会议
智驱力人工智能4 小时前
AI移动监测:仓储环境安全的“全天候守护者”
人工智能·算法·安全·边缘计算·行为识别·移动监测·动物检测
DpHard4 小时前
自用Vscode 配置c++ debug环境
c++·ide·vscode
hy____1235 小时前
C++多态的详细讲解
开发语言·c++
superior tigre5 小时前
C++学习:六个月从基础到就业——C++20:范围(Ranges)进阶
c++·学习·c++20
小葡萄20255 小时前
黑马程序员C++2024版笔记 第0章 C++入门
开发语言·c++·笔记
代码小将5 小时前
力扣992做题笔记
算法·leetcode