题目描述
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−2^31, 2^31 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
分析思路
1.从后向前,依次取出原输入值的每一位;
2.由第一步取出的每一个值,从前向后,不断构造目标反转数(例如原输入123,反转得到321,从3开始取出,即rev = rev * 10 + digit,该表达式也易于代入至不等式);
3.构造的同时,应依据上下界限的不等关系式,对当前环节(该遍历阶段)的数值进行大小检验。
1,2,3可以放入一个循环。
本题的求解可以借鉴带余除法相关知识。
常见错误
1.从后向前构造目标反转数,例如123->321,从1开始,以321=3* 100 + 2* 10 + 1构造,即加数是前一个,以10的幂来表示,表达方式和与不等式的关系复杂。
2.界限检查有误。需以输入正数为例求解不等式:
x<0的情况类似。
3.Python3 的取模运算在 x 为负数时也会返回 [0, 9) 以内的结果,因此这里需要进行特殊判断。同理,Python3 的整数除法在 x 为负数时会向下(更小的负数)取整。
题解
第一次通过:
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
INT_MIN, INT_MAX = (-2**31)//10, (2**31 - 1)//10
# 判断符号,非0数均转换为正数
if x==0:
return x
elif x>0:
c = 1
else:
c = -1
x = 0-x
cache = []
count = 0
while x!=0:
x, left = divmod(x, 10)
cache.append(left)
count += 1
# 数学问题
# 例如123,不对321走倒向加,而是根据规律的等式关系从3开始不断乘10
for i in range(count):
x *= 10
ad = cache.pop(0)
x += ad
# 判空
if cache:
new_tail = cache[0]
else:
continue
# 判断最终目标数的正负
if c==1:
if (x==INT_MAX and new_tail>=8) or (x>INT_MAX):
return 0
else:
if (x==INT_MAX and new_tail==9) or (x>INT_MAX):
return 0
return x*c
# 整合至一个循环
class Solution(object):
def reverse(self, x):
"""
:type x: int
:rtype: int
"""
INT_MIN, INT_MAX = (-2**31)//10, (2**31 - 1)//10
if x==0:
return x
elif x>0:
c = 1
else:
c = -1
x = 0-x
target = 0
while x!=0:
x, left = divmod(x, 10)
new_tail = x % 10
# 数学问题
# 例如123,不对321走倒向加,而是根据规律的等式关系从3开始不断乘10
target *= 10
target += left
#print(x, target)
if not x:
continue
if c==1:
if (target==INT_MAX and new_tail>=8) or (target>INT_MAX):
return 0
else:
if (target==INT_MAX and new_tail==9) or (target>INT_MAX):
return 0
return target*c
官方:
class Solution:
def reverse(self, x: int) -> int:
INT_MIN, INT_MAX = -2**31, 2**31 - 1
rev = 0
while x != 0:
# INT_MIN 也是一个负数,不能写成 rev < INT_MIN // 10
if rev < INT_MIN // 10 + 1 or rev > INT_MAX // 10:
return 0
digit = x % 10
# Python3 的取模运算在 x 为负数时也会返回 [0, 9) 以内的结果,因此这里需要进行特殊判断
if x < 0 and digit > 0:
digit -= 10
# 同理,Python3 的整数除法在 x 为负数时会向下(更小的负数)取整,因此不能写成 x //= 10
x = (x - digit) // 10
rev = rev * 10 + digit
return rev
better:
def reverse_better(
self,
x: int) -> int:
y, res = abs(x), 0
# 则其数值范围为 [−2^31, 2^31 − 1]
boundry = (1<<31) -1 if x>0 else 1<<31
while y != 0:
res = res*10 +y%10
if res > boundry :
return 0
y //=10
return res if x >0 else -res