python实现连续数列相加_【leetcode那些事】312 连续相加数列

这道题是 leetcode 上难度为 medium 的题目。Problems - LeetCode​leetcode.com2eea35ff8e0f380887688449344b1995.png

不过,这道题还是非常值得各位一做的,考的是回溯的思想。如果你的脑子里没有这个意识,可能这道题还不是很好想。不过,各位想过没有,你把这道题拿过来的时候,你的大脑是如何一步步地判断此题需要用回溯呢?首先,这道题的字符串是完整的,也就是说,拆分点没有告诉你,因此,你需要考虑到所有可能的拆分点,一说到考虑所有,就要往回溯去想了,实现方法自然是递归。(有同学问回溯和递归的区别是什么,这是个不错的问题,我以后可能会写文章详细地去讲,不过这里你就先简单记:回溯是一种算法思想,而递归是编程的实现方法。可以这么说:回溯用递归实现)

题意不难理解,leetcode 的自带例子如下:

很清楚,拆分点是可变的,只要有一串序列满足题意就可以了,需要注意的是,题目规定,以 0 开头的数字是非法的。

在把代码写出来前,我们脑子里可以先去思考一下例程,我们举一个例子,试着把完整的例程写出来:

例:1112233558

由于字符串表达数字的间隔不方便,我们可以用一个数组 res 来存储由当前的拆分点拆出来的字符串,如果不理解这句话没关系,我们往下看。

nums = 1112233558, res = [1]

res = [1,1]

res = [1,1,1] 不满足要求,退栈,请搞清楚栈与递归之间的关系。(你甚至可以认为他们是一样的)

res = [1,1,12] 不满足

res = [1,1,122] 不满足

res = [1,1,1223] 不满足

。。。

res = [1,1,12233558] 不满足

res = [1,11]

res = [1,11,2] 不满足

res = [1,11,22] 不满足

res = [1,11,223] 不满足

。。。

res = [1,11,2233558] 不满足

res = [1,112]

res = [1,112,2] 不满足

res = [1,112,23] 不满足

res = [1,112,233] 不满足

。。。

res = [1,112,233558] 不满足

res = [1,1122]

res = [1,1122,3] 不满足

。。。

res = [1,11223,3]

。。。

res = [1,11223,35]

。。。

res = [1,1122233558]

res = [1]

res = []

res = [11]

res = [11,1]

res = [11,1,2] 不满足

。。。

res = [11,1,2233558] 不满足

。。。

res = [11,12]

res = [11,12,2] 不满足

res = [11,12,23] 满足,入栈

res = [11,12,23,3] 不满足

res = [11,11,22,35] 满足

res = [11,12,23,35,5] 不满足

res = [11,12,23,35,58] 满足,return

如果你真的踏踏实实地跟着例程走了一遍,我相信你已经明白了。

不过,递归这块的代码是稍微有点绕,我们一步步来,首先,我们每次都要判断,res 的长度是否大于等于3了,一旦满足这个要求,就要继续判断 res[-1] == res[-2] + res[-3] 如果不满足就要退栈。

因此,我们可以写:

if len(res) >= 3 and res[-1] != res[-2] + res[-3]: # if not satisfied, return

print('not satisfied')

return False

接着,我们剩余的字符串没有了,也就是说都跑到 res 里面去了,而且通过了上面一个 if,即,res[-1] == res[-2] + res [-3] 也就是满足题意了,那么,我们可以就可以返回 True 了,因此,我们可以写:

if num_str == "" and len(res) >= 3: # help avoid only 2 digit

print('correct until now')

return True

再者,我们则要写程序最重要的部分,当程序在运行中的时候,也就是还有剩余的字符串,我们怎么写代码?我们再回过头看看例程,我们知道了,每次我们都会给上一个不满足要求的字符串多填一位,然后在试探一下是否满足要求。同时,我们也要避免,一个数字以 0 为开头,因此,用一个 for 循环,一个 if,和一个嵌套递归就足够了。

于是我们可以写:

for i in range(len(num)):

next = num[:i+1]

print('res',res,'i',i,'next',next)

if (next[0] == '0' and len(next) != 1): # help avoid number starting with 0

print('begin with 0')

continue

if dfs(num[i+1:], res + [int(next)]): # recursive function

return True

是不是仔细看下来的话,这道看似高大上的回溯,也不是很难呢?

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值