【描述】
Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.
【举例】
Example 1:
Input: 121 Output: true
Example 2:
Input: -121 Output: false Explanation: From left to right, it reads -121. From right to left, it becomes 121-. Therefore it is not a palindrome.
Example 3:
Input: 10 Output: false Explanation: Reads 01 from right to left. Therefore it is not a palindrome.
【注意】
Follow up:
Coud you solve it without converting the integer to a string?
【题目翻译】
判断一个十进制整数是否是回文结构,举例:
121 ——> true
-121 ——> false
10 ——> false
而且题目要求不能把整数转换成字符串再进行判断。
【解题思路】
一开始我的思路是, 把后半部分数字压栈,然后依次出栈和前半部分的数字从后往前挨个比较:
比如x = 123321
我依次执行x%10,x= x//10从x中拿出最后一位数压栈, 压到一半以后如下(需要事前求出数字的位数):
3 |
2 |
1 |
然后依次对剩下的x=123, x%10和x=x//10取出末位数, 和弹出的栈顶元素比较大小, 比较过程中有一组不相等说明不是回文,都相等说明是回文。
如果是奇数的话只需要对剩下的x多做一次//10后, 再比较即可。(判断奇只要把长度%2看余数是否位1即可)
【代码v1】
class Solution(object):
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
if x < 0:
return False
length = len(str(x))
odd = True if length%2 == 1 else False
stack = []
for i in range(length//2):
stack.append(x%10)
x = x//10
if odd:
x = x//10
while x != 0:
if x%10 != stack.pop():
return False
x = x//10
return True
然后我想, 可以有更好的解法, 取出来的一半的数字完全可以逆序再重组, 重组完直接跟剩下的前半部分数字比较一下即可。
如123321:
rev = 0
for i in range(len_//2):
rev = rev*10 + x%10
x = x//10
然后直接比较x 和 rev大小即可。
奇数只要把x多做一次//10, 再比较即可。
【代码v2】
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
if x < 0:
return False
xx = x
len_ = 0
while xx != 0:
xx = xx//10
len_ += 1
odd = True if len_%2 == 1 else False
half_num = 0
for i in range(len_//2):
half_num = half_num*10 + x%10
x = x//10
if odd:
x = x//10
return True if half_num == x else False
但是改完之后发现速度并没有提高很多, 看了一下讨论区, 发现其实时间都花费在求x的位数上面, 我们可不可以不求x的位数呢?
答案是可以的:
我们在把x的位数不断抽走的过程中, rev的位数是不断增加的, x的位数不断减小:
如果是奇数的话, 取到一半加1的位置以后x > rev 就变成了x < rev;
我们就可以根据x > rev为循环判断条件
如果是偶数的话,取到一半如果x <= rev, 退出循环, 如果x仍然大于rev, 多取一位, 退出循环
取完之后只有两种情况是回文:
1)奇数:rev//10 == x
2) 偶数: rev == x
【代码v3】
class Solution:
def isPalindrome(self, x):
"""
:type x: int
:rtype: bool
"""
if x < 0 or (x != 0 and x%10 == 0): #末尾以零结束的x无法判断, 单独列出来
return False
rev = 0
while x > rev:
rev = rev*10 + x%10
x = x//10
return rev//10 == x or x == rev