「这是我参与11月更文挑战的第3天,活动详情查看:2021最后一次更文挑战」
题目
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121 是回文,而 123 不是。
示例 1:
输入:x = 121
输出:true
示例 2:
输入:x = -121
输出:false
解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入:x = 10
输出:false
解释:从右向左读, 为 01 。因此它不是一个回文数。
示例 4:
输入:x = -101
输出:false
提示:-231 <= x <= 231 - 1
进阶:你能不将整数转为字符串来解决这个问题吗?
解题思路
通过之前的题目 7.整数反转 我们可以得知反转整数的方法有一下两种:
- 将整数转换为字符串再转为数组进行反转
- 通过数学方法取余求模可以得到
如果我们再比较反转后得到的数与之前的数是否相等,则可以判断是否为回文数。
如果相等,则返回true;否则返回false
同时根据示例我们可以得到一下特点:
- 小于0的数不可能是回文
- 大于0小于10的数一定是回文
- 位数为偶数个的时候不可能是回文
方法一:整数反转 - 数组
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
return parseInt(x.toString().split('').reverse().join('')) === x ? true : false;
};
方法二: 整数反转 - 取余
这种方法下需要考虑到x的正负。
同时因为会改变传进来的x的值,我们需要在一开始的时候保存一下。
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
let temp = x;
let reserve = 0;
if (x < 0) return false;
if (x < 10) return true;
while(x !== 0) {
reserve = reserve * 10 + x % 10;
x = x/10 | 0;
}
reserve = (reserve | 0) === reserve ? reserve : 0;
if (reserve === temp) return true;
return false;
};
看到了大佬更好的解法如下:
var isPalindrome = function(x) {
if(x < 0 || (!(x % 10) && x)) return false;
let x2 = x, res = 0;
while(x2){
res = res * 10 + x2 % 10;
x2 = ~~(x2 / 10);
}
return res === x;
};
方法三:转字符串后循环比较
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
if (x >= 0) {
str = x.toString();
for (let i = 0; i < str.length / 2; i++) {
if (str[i] !== str[str.length - 1 - i]) return false;
}
return true;
} else {
return false;
}
};
方法四:转为字符串后双指针
- 现将数字转为字符串
- 自定义两个指针,一个指向最左边left,一个指向字符串最右边right
- 循环条件是left < right的时候,判断指针指向的值是否相等,不等则返回false。
- 否则左边指针向右移1
- 右边指针左移1
此处判断的是不相等的时候返回false。
为什么不判断相等呢?
我们需要考虑到x = 0 的情况, 其实就不能进循环内部了,所以应该在外面返回true。
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function(x) {
const str = new String(x);
let left = 0, right = str.length - 1;
while(left < right) {
if(str[left] !== str[right]) return false;
left++;
right--;
}
return true;
};
方法五:数学法,除法和取余,数量级
此方法其实同方法二差不多,唯一的区别就是利用了数学里面的数量级来获取位数,而不是通过转为字符串获取。
使用除法和求余获得对应位置的数字,无字符串操作。
- 首先获取当前数量级n
- 通过
x / n获取首位。 - 通过
x % 10获取末位。 (x % n) / 10去除首位和末位,(x % n去除首位,x / 10去除末位),x 位数减 2。n /= 100x 位数减 2, 故n需要除 10^210
以 123421 为例,运算过程如下:
| x | n | x/n | x%10 |
|---|---|---|---|
| -123421 | 100000 | 1 | 1 |
| 2342 | 100 | 2 | 2 |
| 34 | 10 | 3 | 4 |
代码:
/**
* @param {number} x
* @return {boolean}
*/
var isPalindrome = function (x) {
if (x < 0) return false;
if (x < 10) return true;
let n = 10 ** Math.floor(Math.log10(x));
while (n > 1 && x > 0) {
if (Math.floor(x / n) !== x % 10) return false;
x = Math.floor((x % n) / 10);
n /= 100;
}
return true;
};