力扣066 加一
题干
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
输入:digits = [0]
输出:[1]
解析
1、常规法
本题的常规解题思路是从后往前遍历数组,遇到不等于 9 的元素就+1然后退出,遇到 9 则将 9 变为 0 ,然后继续遍历,知道遇到非9元素为止。
值得注意的是,当我们遍历到数组的首元素为 9 时,此时已经没有前一个元素让我们继续遍历了,因此我们需要额外插入一个 1 在数组开头,这可以视为特殊情况单独考虑。
2、取巧法
利用Python灵活的类型转换,虽然给我们的是一个列表,但让我们做的操作确是数字的加法,因此考虑将列表代表的数字转换成int类型的真数字,+1后再转回列表即可。
难点是能不能正确地做出类型转换:
1)整型元素转字符串元素
[1, 2, 3] ——> [‘1’, ‘2’, ‘3’]
2)字符串元素拼接成整个字符串数字
[‘1’, ‘2’, ‘3’] ——> ‘123’
3)字符串数字转整型数字
‘123’ ——> 123
4)+1
123 ——> 124
5)整型数字转字符串数字
124 ——> ‘124’
6)字符串数字分散存放在列表中
‘124’ ——> [‘1’, ‘2’, ‘4’]
7)字符串列表转整型列表
[‘1’, ‘2’, ‘4’] ——> [1, 2, 4]
代码
1、常规法
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
for i in range(len(digits)-1, -1, -1):
if digits[i] != 9:
digits[i] += 1
break
elif digits[i] == 9 and i == 0:
digits[i] = 0
digits.insert(0,1)
else:
digits[i] = 0
return digits
2、取巧法
class Solution:
def plusOne(self, digits: List[int]) -> List[int]:
# 1
digits = list(map(str, digits))
# 2 3
digit = int(''.join(digits))
# 4
digit += 1
reuslts = list()
# 5 6
for d in str(digit):
reuslts.append(d)
# 7
return list(map(int, reuslts))
这里的注释,简单地说明了取巧法每一步分别如何实现,需要注意的是,map()可以很方便地对序列进行批量操作(此处是批量类型转换),但map函数并不是对参数序列进行操作的,而是返回一个迭代器,因此调用map函数后,需要将map返回的迭代器再类型转换成列表类型。
另外,题干里明明说了这样一句话
你可以假设除了整数 0 之外,这个整数不会以零开头。
但是测试用例中却有这样一个用例:
这个操作实在是看不懂。如果考虑这样的测试用例,那么只有常规法可以通过,取巧法是通不过这个用例的,但是其他正常一点的用例用取巧法是没问题的。
正因为如此,我才把这种方法叫做取巧法,因为毕竟这种方法不是出题人的本意。掌握常规法才是正道。