华为 OD 训练营 · 题解精讲
LC9. 回文数
题目描述
给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文,而 123 不是。 示例 1: 输入:x = 121 输出:true 示例 2: 输入:x = -121 输出:false 解释:从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 示例 3: 输入:x = 10 输出:false 解释:从右向左读, 为 01 。因此它不是一个回文数。
题目解析
题目在说什么
简单说,就是给你一个数字,比如 121,你从左边往右边读是“一二一”,从右边往左边读也是“一二一”,那它就是回文数。 但如果是 -121,从左往右读是“负一二一”,从右往左读是“一二一负”,不一样,所以不是回文数。 还有像 10,从左往右是“一零”,从右往左是“零一”,也不一样,所以也不是。
所以关键就是:正着读和反着读,是不是完全一样。
---
思路是怎么来的
我们想一下,怎么判断一个数字正反读一样呢?
生活比喻: 想象你有一串数字写在纸条上,比如 121。你想知道它正着读和反着读是不是一样。 一个最笨的办法是:把纸条翻过来,从最后一个数字开始,一个一个写下来,得到一个新的数字,比如 121 反过来就是 121。然后比较原来的数字和这个新数字,如果一样,就是回文。
但问题来了:如果数字是 123,反过来是 321,不一样,就不是回文。
那怎么“反过来”呢? 比如数字 121,我们想得到它的“反转数”:
- 先拿到最后一位:1(用 121 % 10 得到)
- 然后去掉最后一位:剩下 12(用 121 / 10 得到)
- 再把刚才拿到的 1 放到新数字的个位,新数字现在是 1
- 重复:从 12 拿到最后一位 2,新数字变成 1*10 + 2 = 12,剩下 1
- 再重复:从 1 拿到最后一位 1,新数字变成 12*10 + 1 = 121,剩下 0
- 结束,新数字就是 121,和原来一样,所以是回文。
所以思路就是:把原数字倒过来构造一个新数字,然后比较两者是否相等。
但注意:负数肯定不是回文,因为负号在反转后会跑到末尾,和原来不一样。 还有像 10 这样的,反转后是 01,也就是 1,和原数 10 不一样,所以也不是回文。
---
代码逐步拆解
我们来看一段 Python 代码(其他语言思路一样):
def isPalindrome(x: int) -> bool:
# 特殊情况:负数肯定不是回文
if x < 0:
return False
# 保存原始值,后面要比较
original = x
reversed_num = 0
# 循环直到 x 变成 0
while x > 0:
# 取出 x 的最后一位数字
digit = x % 10
# 把这一位加到反转数的末尾
reversed_num = reversed_num * 10 + digit
# 去掉 x 的最后一位
x = x // 10
# 比较反转后的数和原始数是否相等
return reversed_num == original逐行解释:
1. if x < 0: return False 负数直接排除,因为负号会导致正反读不一样。
2. original = x 因为后面我们要不断修改 x(去掉最后一位),所以先存一份原始值,最后比较用。
3. reversed_num = 0 用来存放反转后的数字。
4. while x > 0: 只要 x 还有数字(还没变成0),就继续循环。
5. digit = x % 10 % 是取余数,比如 121 % 10 = 1,得到最后一位数字。
6. reversed_num = reversed_num * 10 + digit 把当前得到的数字放到反转数的末尾。比如之前 reversed_num 是 1,现在 digit 是 2,那么新 reversed_num = 1*10 + 2 = 12。
7. x = x // 10