力扣066 加一

力扣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 之外,这个整数不会以零开头。

但是测试用例中却有这样一个用例:
这是我运行取巧法代码时报的错
这个操作实在是看不懂。如果考虑这样的测试用例,那么只有常规法可以通过,取巧法是通不过这个用例的,但是其他正常一点的用例用取巧法是没问题的。

正因为如此,我才把这种方法叫做取巧法,因为毕竟这种方法不是出题人的本意。掌握常规法才是正道。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值