Reverse the Digits
给你一个非负整数 n。请返回将它的十进制数字倒序排列后得到的数。倒序后位于开头的零会被去掉,因此 120 会变成 21。
函数
- ninteger
- 要反转的非负整数
- 返回值integer
- 将 n 的各位数字倒序排列后组成的数字
约束条件
0 ≤ n < 109- 反转后的数字也能用有符号 32 位整数表示。
示例
- 输入
- n = 1234
- 输出
- 4321
- 解释
1234的各位数字是 1、2、3 和 4。从末尾开始读,它们是 4、3、2 和 1,也就是4321。
- 输入
- n = 120
- 输出
- 21
- 解释
- 倒着读,
120的数字是 0、2 和 1。数字开头的 0 不计入数值,所以答案是21。
- 输入
- n = 0
- 输出
- 0
- 解释
0只有一位数字,反转后还是0。
进阶
如果 n 是任意 32 位整数,反转后的结果可能无法表示。你该如何在乘法溢出之前检测到这一点?
提示
逐个打开提示,每个都会多透露一点。
哪种算术运算可以得到一个数的最后一位,哪种运算可以去掉它?
n % 10是最后一位数字,n / 10(整数除法)会去掉它。要把数字d放到另一个数字r的末尾,计算r * 10 + d。从
result = 0开始。当n大于0时,把它的最后一位数字移到result的末尾,并从n中去掉这一位。不会出现前导零,因为0 * 10 + 0仍然是0。
题解
在大多数语言中,反转十进制数字的文本只需一行代码,是个不错的初始答案。面试官通常接着会要求你在不使用字符串的情况下实现相同的结果。算术方法依赖两个运算:n % 10 读取最后一位数字,n / 10(整数除法)则移除它。
反转十进制文本
思路
一个数字的各位数字就是它的十进制文本中的字符。把 n 转成文本,反转这些字符,再解析结果:1234 会变成 "1234",再变成 "4321",最后变成 4321。开头的零会自动处理,因为解析 "021" 会得到 21。
工作量和文本长度都会随数字的位数增长,这里的复杂度为 O(log n),最多 9 位。
算法
- 将
n转换为十进制文本。 - 反转这些字符。
- 将反转后的文本解析为整数并返回。
def reverseDigits(n):
# int() ignores the leading zeros that trailing zeros turn into.
return int(str(n)[::-1])用算术弹出和压入数字
思路
从 n 的末尾取出数字,并将每个数字加到 result 的末尾:result * 10 + d 会将当前内容左移一位,并把 d 放在个位上。对于 1234,result 依次变为 4、43、432、4321,而 n 依次变为 123、12、1、0。循环每个数字运行一次。
结果不会出现前导零:对于 120,取出的第一个数字是 0,而 0 * 10 + 0 仍然是 0。当 n = 0 时,循环不会运行,答案是 0。只保留两个整数,因此额外空间为 O(1)。
算法
- 将
result = 0设为初始值。 - 当
n大于0时,计算最后一位数字n % 10。 - 将
result = result * 10 + digit设为新值。 - 使用整数除法,通过
n = n / 10去掉这一位数字。 - 返回
result。
def reverseDigits(n):
result = 0
while n > 0:
result = result * 10 + n % 10 # push the last digit of n
n //= 10 # drop it from n
return result
易错点和边界情况
- 需要进行整数除法时,却使用普通除法。在 JavaScript、Python 3 和 Lua 中,
n / 10会得到123.4,所以n再也不会变回整数,result中会充满小数。请使用Math.floor、//或你所用语言的整数除法。 - 将循环写成
while n >= 10。这样会在处理最后一位数字之前停止,所以1234会变成432。 - 返回反转后的文本,却没有解析它。
"021"不是数字21,因此与预期答案的比较会失败。 - 在 R 中使用
as.character格式化 double。当n以 double 类型存储时,它会将100000000打印为1e+08,反转后的文本就是80+e1。请使用format(n, scientific = FALSE)。
常见问题3
反转一个数字时,末尾的零会怎样?
它们会变成前导零,而数字没有前导零,所以这些零会消失。反转 120 会得到 21,反转 100000000 会得到 1。算术循环会自动去掉这些零,因为向空结果加上 0 后,结果仍然是 0。
反转一个整数的时间复杂度是多少?
循环会对每一位十进制数字运行一次,而数字 n 大约有 log10(n) + 1 位,因此时间复杂度为 O(log n)。算术版本使用 O(1) 的额外空间;字符串版本会将数字存储为文本,空间复杂度为 O(log n)。
反转一个整数会导致溢出吗?
是的,当输入可以是任意 32 位整数时:1000000009 符合范围,但它反转后的 9000000001 不符合。这里 n 小于 10^9,因此反转后的数字最多有 9 位,并且始终符合范围。
相似题目
运用相同思路的题目。做两三道,才能真正掌握一种模式。
def reverseDigits(n):
# 在这里编写代码测试 #1
测试 #2
测试 #3
参数
n = 1234
预期输出
4321