题目描述
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
例如,121 是回文,而 123 不是。
示例
输入:x = 121
输出:true
复制代码
解题思路
-
第一个想法是将数字转换为字符串,将翻转后的字符串与原字符串比较,如果相同则为回文数。但是数字转数组、数组转字符串,需要额外的空间一定是。
-
第二个是:如果该数是回文数,其后半部分反转后应该与原始数字的前半部分相同。
- 输入 1221,我们可以将数字 1221 的后半部分
21
反转为12
,然后与前部分比较 - 因为二者相同,我们得知数字 1221 是回文
- 输入 1221,我们可以将数字 1221 的后半部分
-
具体思路为:
-
先处理一些临界情况
- 所有负数都不可能是回文,例如:
-123
。 - 除了 0 以外,所有个位是 0 的数字不可能是回文,因为最高位不等于 0
- 所有负数都不可能是回文,例如:
-
现在,来考虑如何反转后半部分的数字。
- 对于数字 1221,如果执行
1221 % 10
,我们将得到最后一位数字1
- 要得到倒数第二位数字,我们可以先通过除以 10 把最后一位数字从 1221 中移除,
1221 / 10 = 122
,再求出上一步结果除以 10 的余数,122 % 10 = 2
,就可以得到倒数第二位数字。 - 如果我们把最后一位数字乘以 10,再加上倒数第二位数字,
1 * 10 + 2 = 12
,就得到了我们想要的反转后的数字。 - 如果继续这个过程,我们将得到更多位数的反转数字。
- 对于数字 1221,如果执行
-
如何知道反转数字的位数已经达到原始数字位数的一半?
- 由于整个过程我们不断将原始数字除以 10,然后给反转后的数字乘上 10,所以,原始数字逐渐变小,反转后的数字逐渐变大。
- 当原始数字小于或等于反转后的数字时,就意味着我们已经处理了一半位数的数字了。
-
说明
偶数:
次数 | x | 得到除10余数 | 反转后的数字 |
---|---|---|---|
0 | 123321 | 0 | |
1 | 12332 | 1 | 0*10+1=1 |
2 | 1233 | 2 | 1*10+2=12 |
3 | 123 | 3 | 12*10+3=123 |
4 | x<=123停止 |
奇数:
次数 | x | 得到除10余数 | 反转后的数字 |
---|---|---|---|
0 | 12321 | 0 | |
1 | 1232 | 1 | 0*10+1=1 |
2 | 123 | 2 | 1*10+2=12 |
3 | 12 | 3 | 12*10+3=123 |
4 | x<=123停止 |
因此奇数时 代码要做一些处理
代码
var isPalindrome = function (x) {
// 特殊情况:
// 如上所述,当 x < 0 时,x 不是回文数。
// 同样地,如果数字的最后一位是 0,为了使该数字为回文,则其第一位数字也应该是 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);
}
// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。
// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,revertedNumber = 123,
// 由于处于中位的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。
return x === revertedNumber || x === Math.floor(revertedNumber / 10);
};
复制代码