回文数
1、题目:
判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。
示例 1:
输入: 121
输出: true
示例 2:
输入: -121
输出: false
解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。
示例 3:
输入: 10
输出: false
解释: 从右向左读, 为 01 。因此它不是一个回文数。
进阶:
你能不将整数转为字符串来解决这个问题吗?
2、解题步骤:
(1) 方案一:利用字符串做反转
a、题解:
将整数x
变成字符串,然后再拷贝一份字符串,将拷贝后的字符串反转一下。
再比较原字符串和拷贝后的字符串是否相等。
b、代码:
class Solution:
"""方案一"""
def isPalindrome(self, x: int) -> bool:
return str(x) == str(x)[::-1]
def test():
s = Solution()
assert s.isPalindrome(121) is True
assert s.isPalindrome(-121) is False
assert s.isPalindrome(10) is False
c、运行结果:
(2) 方案二:取模运算
a、题解:
用取模运算,就能拿到数字的最后一位,然后用res*10 + x%10
这种方式就可以反向的拼接出来了。
12321通过 %10 得到1,再将老数字12321/10=1232
将1232%10得到2,再将新数字1*10 + 2得到12,同时老数字1232/10=123
将123%10得到3,新数字12*10 + 3得到123,同时老数字123/10=12
将12%10得到2,新数字123*10 + 2得到1232,同时老数字12/10=1
将1%10得到1,新数字1232*10 + 1得到12321,同时老数字1/10=0
最后比较原数字12321
和新拼接出来的数字12321。
注意:
如果我们输入的是最大32位整数2147483647,这个数字本身是没有问题,是一个合法的32位最大整数,用int存储也没问题,但是如果将这个数字反转的话,其大小超过了32位最大整数,也就是会溢出
那是否要把变量的类型改成long来存储呢,这样反转后的数字就不会溢出了。
其实不用,虽然我们反转的数字不对,但是返回的结果却是对的。
因为32位整数中最大的回文数 是2147447412,这个数字是比最大32位整数 小的。
所以超过2147447412大小的数字也就不是回文数字了,虽然我们经过反转后的数字溢出了,但它的返回结果却是对的,这也算是歪打正着,于是我们继续用int类型来保存数字,也没问题。
b、代码:
class Solution:
"""方案二"""
def isPalindrome(self, x: int) -> bool:
if x < 0:
return False
ans = 0
old = x
while x > 0:
ans = ans * 10 + x % 10
x //= 10
return ans == old
def test():
s = Solution()
assert s.isPalindrome(121) is True
assert s.isPalindrome(-121) is False
assert s.isPalindrome(10) is False
assert s.isPalindrome(2147483647) is False
c、运行结果:
(2) 方案三:反转一半数字
a、题解:
b、代码:
class Solution:
"""方案三"""
def isPalindrome(self, x: int) -> bool:
# 小于0 或 能被10整除且不为0的数字,直接返回False
if x < 0 or (x % 10 == 0 and x != 0):
return False
ans = 0
while x > ans:
ans = ans * 10 + x % 10
x //= 10
# 原数字长度为偶数,原数字 == 新数字
# 原数字长度为奇数,原数字 == 新数字 // 10
return x == ans or x == (ans // 10)
def test():
s = Solution()
assert s.isPalindrome(-121) is False
assert s.isPalindrome(10) is False
assert s.isPalindrome(12321) is True
assert s.isPalindrome(123321) is True
c、运行结果: