题目
给你一个 32 32 32 位的有符号整数 x x x ,返回将 x x x 中的数字部分反转后的结果。如果反转后整数超过 32 32 32 位的有符号整数的范围 [ − 2 31 , 2 31 − 1 ] [−2 ^ {31} , 2 ^ {31} − 1] [−231,231−1] ,就返回 0 0 0。
示例
- 输入:
x
=
123
x = 123
x=123
输出: 321 321 321 - 输入:
x
=
−
123
x = -123
x=−123
输出: − 321 -321 −321 - 输入:
x
=
120
x = 120
x=120
输出: 21 21 21 - 输入:
x
=
0
x = 0
x=0
输出: 0 0 0
思路
1. 字符串翻转
先将输入的数字变为字符串,然后分为有无 ‘ − ’ ‘-’ ‘−’两种情况,没有负号直接翻转,有负号翻转到字符下标为 ‘ 1 ’ ‘1’ ‘1’不再翻转,前面再加上 ‘ − ’ ‘-’ ‘−’即可。翻转可以使用切片来实现。
- 时间复杂度: O ( n ) O(n) O(n)
- 空间复杂度: O ( n ) O(n) O(n)
在Python中,可以使用切片(slicing)操作对序列(如字符串、列表、元组等)进行切割或抽取子序列。
切片的基本形式是: s e q u e n c e [ s t a r t : s t o p : s t e p ] sequence[start:stop:step] sequence[start:stop:step] 。
其中, s t a r t start start 是起始索引(包括该索引), s t o p stop stop 是终止索引(不包括该索引), s t e p step step 是步长(默认为 1)。
如果 s t e p step step 为正整数,则表示从左往右取子序列。
如果 s t e p step step 为负整数,则表示从右往左取子序列。
class Solution:
def reverse(self, x: int) -> int:
# 将数字转为字符串
str_num = str(x)
# 如果存在负号
if '-' in str_num:
# 翻转到下标为1 即可
reverse_s = '-'+ str_num[:0:-1]
# 没有负号 直接翻转
else:
reverse_s = str_num[::-1]
# 再将字符转换为数字输出
int_reverse_s = int(reverse_s)
# 范围判断
if int_reverse_s >= 2**31 or int_reverse_s <= -2**31:
return 0
else:
return int_reverse_s
2. 按位转换
从输入的数字中反复右移推出数字,对于计算结果再推入数字。推出就是取模再除以 10 10 10,推入就是乘以 10 10 10 再加上数字。
- 时间复杂度: O ( l o g ( x ) ) O(log(x)) O(log(x))
- 空间复杂度: O ( 1 ) O(1) O(1)
负数取整
Python 中的整除运算符(//)所做的运算。当两个操作数都为整数时,// 返回一个整数,表示整数除法的结果向下取整的值。
例如,对于 123 // 10 来说,整数除法的结果为 12.3,向下取整的值为 12,因此该运算的结果为 12。
对于 -123 // 10,同样是进行整数除法运算,结果为 -12.3,向下取整的值为 -13,因此该运算的结果为 -13。
判断溢出的解释
官方解释
class Solution:
def reverse(self, x: int) -> int:
INT_MIN, INT_MAX = -2 ** 31, 2 ** 31 - 1
rev_num = 0
while x != 0:
# 为什么这么判断看以上解释
if rev_num < INT_MIN // 10 +1 or rev_num > INT_MAX // 10:
# 取模
res = x % 10
# 当输入为负数时,具体解释看以上解释
if x < 0 and res > 0:
res -= 10
# 推出下一个数字
x = x // 10
# 对结果推入新的数字
rev_num = res + rev_num * 10
return rev_num
ChatGPT改进后的写法
class Solution:
def reverse(self, x: int) -> int:
if x < 0:
flag = -1
x = -x
else:
flag = 1
rev = 0
while x > 0:
rev = rev * 10 + x % 10
x //= 10
rev *= flag
# 判断还是用第二种方法
if rev >= 2**31 or rev <= -2**31:
return 0
else:
return rev