首页 简历|笔试面试

9.回文数

  • 25年9月4日 发布
  • 263.48KB 共6页
9.回文数9.回文数9.回文数9.回文数9.回文数

9. 回文数

鲁迅说过,我不知道什么是算法,但是我知道二哥写的 LeetCode 题解真不错。

题意

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

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

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

示例

输入:x = 121

输出:true

输入:x = -121

输出:false

解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。

输入:x = 10

输出:false

解释:从右向左读, 为 01 。因此它不是一个回文数。

分析

读完这道题目,我们需要先搞清楚什么是回文,回文就是正着读和反着读都是一样的,比

如 121,12321,1234321 等等,那么我们如何判断一个数是不是回文数呢?

我第一时间想到的是将数字转成字符串,然后通过 StringBuilder 的 reverse() 方法来翻转

字符串,最后比较两个字符串是否相等,如果相等的话,就说明是回文数,否则就不是回

文数。

class Solution {

public boolean isPalindrome(int x) {

// 数字转字符串

String str = String.valueOf(x);

// 把字符串放入 StringBuilder 中

StringBuilder sb = new StringBuilder(str);

// 利用 StringBuilder 的 reverse() 方法翻转字符串

// 然后调用 equals() 方法比较两个字符串是否相等

return sb.reverse().toString().equals(str);

}

}

咦,竟然能打败 30% 的 Java 用户,别骗我啊,这么简单的题,这么低的效率,我不信。

009.%E5%9B%9E%E6%96%87%E6%95%B0-20240103194017.png

当然了,看似简单的代码背后,其实蕴藏了很多玄机,我们来分析一下。

①、String.valueOf(x)

这个方法可以把整数转成字符串,我在《二哥的 Java 进阶之路》上曾讲过这个方法。

当然了,也可以通过 x + "" 来完成转换,不过 + 号操作符的背后,其实调用的是

StringBuilder 的 append() 方法。

这个我们在讲字符串拼接时曾讲过,不知道大家还记得不?

那后面我们其实又 new 了一个 StringBuilder 对象,所以这里就直接采用

String.valueOf(x) 来完成转换了。

②、StringBuilder sb = new StringBuilder(str);

这里我们把字符串放入 StringBuilder 中,这个也是我在《二哥的 Java 进阶之路》上曾讲

过的,不知道大家还记得不?

包括 reverse() 方法,前面的题解 007.整数反转 也讲过了,这里就不再赘述了。

③、equals(str)

比较两个字符串是否相等,这个我在《二哥的 Java 进阶之路》上也曾讲过了,源码也带

着大家分析过。

分析 2

前面我们反转的是整个数字,那其实我们可以只反转一半的数字,比如 1234321,我们

只需要反转后面一半的数字 321,然后和前面一半的数字 123 进行比较,如果相等,就说

明是回文数,否则就不是回文数。

奇数的话去掉中间的数字。

来看题解,主要用到的还是乘法、取余和除法:

class Solution {

public boolean isPalindrome(int x) {

// 负数不是回文数

// 如果数字的最后一位是 0,为了使该数字为回文,

// 则其第一位数字也应该是 0,只有 0 满足这一属性

if (x < 0 || (x % 10 == 0 && x != 0)) {

return false;

}

int revertedNumber = 0;

while (x > revertedNumber) {

revertedNumber = revertedNumber * 10 + x % 10;

x /= 10;

}

// 当数字长度为奇数时,我们可以通过 revertedNumber/10 去除处于中位的数字。

// 例如,当输入为 12321 时,在 while 循环的末尾我们可以得到 x = 12,

revertedNumber = 123,

// 由于中间的数字不影响回文(它总是与自己相等),所以我们可以简单地将其去除。

return x == revertedNumber || x == revertedNumber / 10;

}

}

1. 处理特殊情况:

– 负数不是回文数,因为有负号。

– 如果一个数的最后一位是 0,要使其为回文,则第一位数字也必须是 0。唯一

满足这个条件的数字就是 0。

2. 反转一半的数字:

– 我们通过 while 循环将最后一位数字移动到 reversedNumber 的末尾,同时将

原始数字除以 10,来反转数字的后半部分。

– 当原始数字小于或等于反转后的数字时,意味着我们已经处理了一半或超过一

半的数字。

3. 比较前半部分和后半部分:

– 如果数字的长度是偶数,反转后的数字应与剩余的原始数字相等。

– 如果数字长度是奇数,则通过将反转后的数字除以 10 去除中间的数字,然后

比较剩余部分。

我们来模拟一下整个题解的过程,比如 1234321:

当输入的数字是 1234321 时,我们来模拟一下判断回文数的过程。按照之前提供的算

法,我们将逐步反转数字的后半部分,并与前半部分进行比较。

初始状态

• 原始数字 x = 1234321

• 反转后的数字 revertedNumber = 0

迭代过程

1. 第一次迭代:

– 取 x 的最后一位:1234321 % 10 = 1

– 将这一位加入 revertedNumber:revertedNumber = 0 * 10 + 1 = 1

– 去掉 x 的最后一位:x = 1234321 / 10 = 123432

此时,x = 123432,revertedNumber = 1。

2. 第二次迭代:

– 取 x 的最后一位:123432 % 10 = 2

– 更新 revertedNumber:revertedNumber = 1 * 10 + 2 = 12

– 更新 x:x = 123432 / 10 = 12343

此时,x = 12343,revertedNumber = 12。

3. 第三次迭代:

– 取 x 的最后一位:12343 % 10 = 3

– 更新 revertedNumber:revertedNumber = 12 * 10 + 3 = 123

– 更新 x:x = 12343 / 10 = 1234

此时,x = 1234,revertedNumber = 123。

4. 第四次迭代:

– 取 x 的最后一位:1234 % 10 = 4

– 更新 revertedNumber:revertedNumber = 123 * 10 + 4 = 1234

– 更新 x:x = 1234 / 10 = 123

此时,x = 123,revertedNumber = 1234。

结束条件

在第四次迭代后,x(123)不再大于 revertedNumber(1234)。此时我们停止迭代。

比较前后半部分

• 现在,我们比较 x 和 revertedNumber / 10(1234 / 10 = 123)。

• 由于 x == revertedNumber / 10(123 == 123),我们可以判断输入的数字是回文

数。

很好理解,我们来看一下题解效率:

009.%E5%9B%9E%E6%96%87%E6%95%B0-20240103210929.png

咦,竟然只打败了 55% 的 Java 用户,看来还有优化的空间啊!

不应该啊,代码没有优化的空间了呀,把代码注释全部删掉,然后再执行一遍。

009.%E5%9B%9E%E6%96%87%E6%95%B0-20240103211725.png

好家伙,这次直接打败 98% 的 Java 用户了,看来注释也是有代价的,哈哈哈。

LeetCode 这波计算方式,我只能说服了,不过为了让大家更好的理解代码,所以我还是

会保留注释的。

总结

这道题目,我觉得最重要的就是理解题意,然后就是理解回文数的含义。

不管是用字符串来解决,还是用数学方法来解决,我觉得都是可以的。

Java 的优势不就是 JDK 帮我们提供了无数牛逼的 API 吗?如果不用的话,学 Java 干嘛?

直接学 C 语言不就行了?

简单梳理一下我们用到的基础知识:

• String.valueOf(x):把整数转成字符串,我在介绍字符串源码的时候讲过。

• reverse():字符串反转,我在介绍 StringBuilder 的时候讲过。

• equals():比较两个字符串是否相等,我在介绍 equals()与==的时候讲过。

当然了,要想学好算法,数学还是要好一点,这样才能更好地运用乘法、取余和除法来解

决问题。

力扣链接:https://leetcode.cn/problems/palindrome-number/

开通会员 本次下载免费

所有资料全部免费下载! 推荐用户付费下载获取返佣积分! 积分可以兑换商品!
一键复制 下载文档 联系客服