leetcode 306.累加数

今天在leetcode遇到一道很有意思的题。

累加数是一个字符串,组成它的数字可以形成累加序列。

一个有效的累加序列必须至少包含 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

好嘛,第一想法,为了给这个序列“起个头”,不用二重循环是不行了。

因为总要依次地确定第一个数,第二个数的值,否则无法产生相应的序列。

因为我用的是python,所以采取了直接解析数字的方法。

以下便是主体部分:

for i in range(1,len(num)//2+1):
            a=int(num[:i])
            j=1
            while j+i<(len(num)+i)//2+1:
                b=int(num[i:i+j])
                if junge(a,b,num):
                    return True
                j+=1

这个边界部分是来源于一个数字的基本性质:如果一个数字大于a另一个数字b,那么a的位数至少与b一样,或者多于b。

所以啊,假如我的边界值获得为a=1,b=123,那么余下的58必然不是累加序列里的一个(来源示例1)。

现在主要是junge函数了,我们要由第一二个数字来判断这整个序列的关系。

我写的是这样:(一会讲解)

def junge(a,b,s):
            c=a+b
            temp=str(a)+str(b)+str(c)
            if s==temp:
                return True
            elif len(s)<len(temp):
                return False
            if s[:len(temp)]==temp:
                return junge(b,c,s[len(str(a)):])
            else:
                return False

采用了递归的手法,首先我们获得a,b,a+b的这个小序列,如果恰好字符串相等了,是正确的,如果比num还长,那一定是num后面的数字不够用了,那么false。

第二个if语句:比较同长度的一段,并且实际上每次我们把s都“截掉”已经比较完毕的段。所以如果这段如果一样了,那么比较由b,c为起始的序列段,即类似斐波尼茨序列那种。


综合来看,实际上python传递的是引用,所以分割字符串的代价很小,否则这么来回切割,必然不能AC。

下面是完整AC代码:

class Solution:
    def isAdditiveNumber(self, num):
        """
        :type num: str
        :rtype: bool
        """
        def junge(a,b,s):
            c=a+b
            temp=str(a)+str(b)+str(c)
            if s==temp:
                return True
            elif len(s)<len(temp):
                return False
            if s[:len(temp)]==temp:
                return junge(b,c,s[len(str(a)):])
            else:
                return False


        for i in range(1,len(num)//2+1):
            a=int(num[:i])
            j=1
            while j+i<(len(num)+i)//2+1:
                b=int(num[i:i+j])
                if junge(a,b,num):
                    return True
                j+=1

        return False


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值