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
。此时,我们已经处理了原数字的一半。最后,比较
x
和revertedNumber
。如果数字x
的位数为偶数,它们应该相等;如果为奇数,反转后的数字会比剩下的一半多一位,此时需要将revertedNumber
除以 10 再比较。
关键步骤
处理特殊情况:所有负数都不是回文数。另外,如果一个数的末尾是 0,要成为回文数,它必须是 0 本身。
初始化:创建一个变量
revertedNumber = 0
。循环反转:当
x > revertedNumber
时,持续循环。 a.revertedNumber = revertedNumber * 10 + x % 10
:构建反转数。 b.x = Math.floor(x / 10)
:消去x
的最后一位。比较结果: 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) 我们只使用了常数个额外变量。
相关题目
总结
本题是数学运算与算法思想结合的经典题目。通过将问题转化为数字反转,可以避免字符串操作。而“反转一半”的优化,更是体现了在处理边界问题(如整数溢出)时的缜密思考。