本系列适合跟我一样新入门的同学,我会从最基础的方法一步一步优化,所有代码都可以直接复制运行,希望有所帮助。如果喜欢可以订阅本系列(基于python3)
先看题目:
给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。
如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。
假设环境不允许存储 64 位整数(有符号或无符号)。
示例 1:
输入:x = 123
输出:321
示例 2:
输入:x = -123
输出:-321
示例 3:
输入:x = 120
输出:21
示例 4:
输入:x = 0
输出:0
解法一 转数组,反向,合并
由于本人是小白,第一反应就是 将字符串拆分成数组,反向以后再合并起来。
操作逻辑: -1234 --> [ '-','1','2','3','4' ] -->[ '4','3','2','1','-' ]
这里要注意 不能把负号一起拆分到数组里,所以要把负号提出来
操作逻辑: -1234 --> '-' [ '1','2','3','4' ] --> '-' [ '4','3','2','1'] --> -4321,提取负号的方式有很多,按自己理解操作就可以。
def reverse(x: int) -> int:
# 判断正负数,最后结果乘以symbol即可
symbol = 1 if x > 0 else -1
# 获得x的绝对值
x = abs(x)
# x转为字符串
x = str(x)
# x转为数组
x = list(x)
# 反向列表中元素
x.reverse()
# 转回数字,并添加原本的负号
x = int("".join(x)) * symbol
# 判断如果不在区间内就return 0
return x if -2 ** 31 < x < 2 ** 31 - 1 else 0
print(reverse(-123))
解法二 直接反向字符串
因为字符串转成数组 再转回来太麻烦了,所以这里有没有办法直接反向字符串呢? 使用python的字符串截取:
num = "12345678"
print(num[::-1])
# 打印结果为 : 87654321
操作逻辑: -1234 --> '-' '1234' --> '-' '4321' --> -4321
def reverse(x: int) -> int:
# 判断正负数,最后结果乘以symbol即可
symbol = 1 if x > 0 else -1
# 获得x的绝对值,并转为字符串
x = str(abs(x))
# 反向字符串
x = x[::-1]
# 转为int 并添加正负号
x = int(x) * symbol
# 返回
return x if -2 ** 31 < x < 2 ** 31 - 1 else 0
print(reverse(-214748364))
精简一下:
def reverse(x: int) -> int:
x = int(str(abs(x))[::-1]) * (1 if x > 0 else -1)
return x if -2 ** 31 < x < 2 ** 31 - 1 else 0
print(reverse(-214748364))
解法三 取余
思路就是通过取余获得最后一位,写个while循环遍历一遍以后,就能按倒叙得到数字了。重新拼起来就可以,唯一要注意的就是要先获得绝对值再取余,否则python会给你一些惊喜。
def reverse(x: int) -> int:
result = str()
symbol = 1 if x == abs(x) else -1
x = abs(x)
while x != 0:
result = result + str(x % 10)
x = x // 10
x = int(result) * symbol
return x if -2 ** 31 < x < 2 ** 31 - 1 else 0
print(reverse(-214748364))
解法三 取余的优化
每次都把值转成str,拼接到result字符串后,最后再转成int,感觉还是浪费了很多性能。有没有办法不转成str格式,直接int格式操作呢?有办法,思路如下:
def reverse(x: int) -> int:
result = 0
symbol = 1 if x == abs(x) else -1
x = abs(x)
while x != 0:
result = result*10 + x % 10
x = x // 10
x = result * symbol
return x if -2 ** 31 < x < 2 ** 31 - 1 else 0
print(reverse(-214748364))
解法三 取余的优化-位运算
在最后判断 x的范围时,用位运算而不是 2**31
2**31 位运算等价于 1<<31
def reverse(x: int) -> int:
result = 0
symbol = 1 if x == abs(x) else -1
x = abs(x)
while x != 0:
result = result*10 + x % 10
x = x // 10
x = result * symbol
return x if -1<<31 < x < 1 << 31 - 1 else 0
print(reverse(-214748364))