306 累加数(高精度加法)

1. 问题描述:

累加数是一个字符串,组成它的数字可以形成累加序列。一个有效的累加序列必须至少包含 3 个数。除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和。给定一个只包含数字 '0'-'9' 的字符串,编写一个算法来判断给定输入是否是累加数。说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。

示例 1:

输入: "112358"
输出: true 
解释: 累加序列为: 1, 1, 2, 3, 5, 8 。1 + 1 = 2, 1 + 2 = 3, 2 + 3 = 5, 3 + 5 = 8

示例 2:

输入: "199100199"
输出: true 
解释: 累加序列为: 1, 99, 100, 199。1 + 99 = 100, 99 + 100 = 199

进阶:

你如何处理一个溢出的过大的整数输入?
说明: 累加序列里的数不会以 0 开头,所以不会出现 1, 2, 03 或者 1, 02, 3 的情况。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/additive-number

2. 思路分析:

分析题目可以知道我们可以使用三个int类型的变量a, b, c固定两个加数对应的字符串位置,其中num[a + 1:b]表示第一个加数,num[b + 1: c]为第二个加数,使用两层循环就可以表示变量b和c的位置,a一开始的时候为-1这样可以表示从0开始截取的若干个位置对应的数字为第一个加数,所以使用两层循环即可表示两个加数。因为需要去除掉前导0,所以第一个加数与第二个加数是不能够存在前导0的,判断第一个加数是否存在前导0:b - a > 1 and num[a + 1] == "0" 说明第一个加数位数大于1且第一位是0所以存在前导0,对于第二个加数也是类似的,c -b > 1 and num[b + 1] == "0"说明第二个加数存在前导0。因为使用的是python语言所以使用字符串的切片操作截取字符串得到对应的两个加数x, y,然后使用高精度加法计算两个字符串对应的数字相加的结果(高精度加法使用数组或者列表来存储两个加数对应位置上的数字然后模拟两个数字相加的过程最后返回字符串结果),然后判断相加的结果是否等于num中截取的字符串对应的结果,如果相等那么移动a, b, c的位置进行下一个两个加数相加的操作,否则break,最后判断一下c + 1是否等于num的长度,如果相等说明是一个有效的累加序列。

3. 代码如下:

class Solution:
    # 高精度加法
    def add(self, a: str, b: str):
        A, B, C = list(), list(), list()
        # 逆序遍历的目的是为了得到从低位开始的数字这样方便相加的时候从低位开始相加
        for i in range(len(a) - 1, -1, -1):
            A.append(int(a[i]))
        for i in range(len(b) - 1, -1, -1):
            B.append(int(b[i]))
        i, t = 0, 0
        while i < len(A) or i < len(B) or t:
            if i < len(A): t += A[i]
            if i < len(B): t += B[i]
            C.append(t % 10)
            t //= 10
            i += 1
        z = ""
        for i in range(len(C) - 1, -1, -1):
            z += str(C[i])
        return z

    def isAdditiveNumber(self, num: str) -> bool:
        for i in range(len(num)):
            for j in range(i + 1, len(num)):
                a = -1
                b = i
                c = j
                while True:
                    # 判断第一个加数是否存在前导0
                    if b - a > 1 and num[a + 1] == "0": break
                    # 判断第二个加数是否存在前导0
                    if c - b > 1 and num[b + 1] == "0": break
                    # 第一个加数
                    x = num[a + 1:a + 1 + b - a]
                    # 第二个加数
                    y = num[b + 1:b + 1 + c - b]
                    z = self.add(x, y)
                    if num[c + 1:c + 1 + len(z)] != z: break
                    # 移动a,b,c的位置 
                    a = b
                    b = c
                    c = c + len(z)
                    if c + 1 == len(num): return True
        return False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值