[路飞]_回文数

9. 回文数

题目描述

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

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

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

示例

输入:x = 121
输出:true
复制代码

解题思路

  • 第一个想法是将数字转换为字符串,将翻转后的字符串与原字符串比较,如果相同则为回文数。但是数字转数组、数组转字符串,需要额外的空间一定是。

  • 第二个是:如果该数是回文数,其后半部分反转后应该与原始数字的前半部分相同。

    • 输入 1221,我们可以将数字 1221 的后半部分 21 反转为 12,然后与前部分比较
    • 因为二者相同,我们得知数字 1221 是回文
  • 具体思路为:

    • 先处理一些临界情况

      • 所有负数都不可能是回文,例如:-123
      • 除了 0 以外,所有个位是 0 的数字不可能是回文,因为最高位不等于 0
    • 现在,来考虑如何反转后半部分的数字。

      • 对于数字 1221,如果执行 1221 % 10,我们将得到最后一位数字 1
      • 要得到倒数第二位数字,我们可以先通过除以 10 把最后一位数字从 1221 中移除,1221 / 10 = 122,再求出上一步结果除以 10 的余数,122 % 10 = 2,就可以得到倒数第二位数字。
      • 如果我们把最后一位数字乘以 10,再加上倒数第二位数字,1 * 10 + 2 = 12,就得到了我们想要的反转后的数字。
      • 如果继续这个过程,我们将得到更多位数的反转数字。
    • 如何知道反转数字的位数已经达到原始数字位数的一半?

      • 由于整个过程我们不断将原始数字除以 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);
};
复制代码

猜你喜欢

转载自juejin.im/post/7040725294969257997