0009.回文数

难度:🟢 简单

标签数学

链接9. 回文数

题目描述

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

  • 例如,121 是回文数,而 123 不是。

示例 1:

输入:x = 121
输出:true

示例 2:

输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

示例 3:

输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。

解题思路

核心思想

本题的核心是判断一个数字正向和反向读取是否相同。一个常见的思路是将数字转换为字符串,然后判断字符串是否回文。但题目进阶要求不使用字符串。因此,我们需要通过数学运算来反转数字的一部分或全部,然后进行比较。

思路选择

反转一半数字 是解决此问题的最优思路。

  • 如果我们将整个数字反转,可能会遇到整数溢出的问题(例如,一个很大的数字反转后可能超出数字类型的表示范围)。

  • 通过只反转数字的后半部分,可以巧妙地避免溢出。我们不断地从原数字 x 的末尾取数,构建一个新的反转数 revertedNumber,直到 x 小于或等于 revertedNumber。此时,我们已经处理了原数字的一半。

  • 最后,比较 xrevertedNumber。如果数字 x 的位数为偶数,它们应该相等;如果为奇数,反转后的数字会比剩下的一半多一位,此时需要将 revertedNumber 除以 10 再比较。

关键步骤

  1. 处理特殊情况:所有负数都不是回文数。另外,如果一个数的末尾是 0,要成为回文数,它必须是 0 本身。

  2. 初始化:创建一个变量 revertedNumber = 0

  3. 循环反转:当 x > revertedNumber 时,持续循环。 a. revertedNumber = revertedNumber * 10 + x % 10:构建反转数。 b. x = Math.floor(x / 10):消去 x 的最后一位。

  4. 比较结果: a. 如果 x 的位数为偶数,循环结束时 x 应该等于 revertedNumber。 b. 如果 x 的位数为奇数,循环结束时 x 应该等于 Math.floor(revertedNumber / 10)。 c. 将这两种情况合并判断即可。

代码实现

/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function (x) {
    // 特殊情况:负数或末尾是0但非0的数
    if (x < 0 || (x % 10 === 0 && x !== 0)) {
        return false;
    }

    let revertedNumber = 0;
    while (x > revertedNumber) {
        revertedNumber = revertedNumber * 10 + x % 10;
        x = Math.floor(x / 10);
    }

    // 判断偶数长度和奇数长度的情况
    return x === revertedNumber || x === Math.floor(revertedNumber / 10);
};

原始代码

您提供的解法通过反转整个数字来判断,逻辑正确且直观。

/**
 * @param {number} x
 * @return {boolean}
 */
var isPalindrome = function (x) {
    // 负数不是回文数
    if (x < 0) return false;
    let revertNum = 0, originNum = x;
    // 循环反转整个数字
    while (originNum !== 0) {
        revertNum = revertNum * 10 + originNum % 10;
        originNum = Math.floor(originNum / 10);
    }

    // 比较反转后的数字和原始数字
    return revertNum === x;
};
  • 优点:思路清晰,易于理解,直接将数字反转进行比较。

  • 待改进:当 x 是一个非常大的数字时(例如接近 Number.MAX_SAFE_INTEGER),revertNum 在构建过程中可能会超出 JavaScript 的安全整数范围,导致精度问题或溢出。推荐解法中“反转一半”的技巧可以完美地避免这个问题。

复杂度分析

  • 时间复杂度O(log₁₀ n) 其中 n 是整数 x。每次循环我们将输入除以 10,所以循环次数与 x 的位数成正比。

  • 空间复杂度O(1) 我们只使用了常数个额外变量。

相关题目

总结

本题是数学运算与算法思想结合的经典题目。通过将问题转化为数字反转,可以避免字符串操作。而“反转一半”的优化,更是体现了在处理边界问题(如整数溢出)时的缜密思考。

Copyright © Jun 2025 all right reserved,powered by Gitbook该文件修订时间: 2025-07-03 17:35:08

results matching ""

    No results matching ""

    results matching ""

      No results matching ""