首先是基本的,数组n中取任意个数字,和为goal
如果是两个数字,那就直接遍历即可。多个数字也能遍历好像,不过肯定特别麻烦所以我要想想该怎么弄
这里用递归解决问题
先附上别人的代码
作者 WizardOz
import random
lst = list(range(1,21))
lst.reverse()
def solve(lst,goal,result = []):
if goal > sum(lst):
return
for i in range(len(lst)):
if lst[i] > goal:
continue
elif lst[i] == goal:
print(result + [lst[i],])
continue
else:
solve(lst[i + 1:],goal - lst[i],result + [lst[i],])
solve(lst,180)
第一点、有个很有用的点,数组【1:】表示分片,取第一个元素之后,也即为数组去掉第一个元素。最好的一点是有效的避免了值的溢出,不会再提示数组下标越界。
第二点、递归结构有一个循环也就代表着有很多个循环,或者说路径。这一点在理解递归时候也很有用。比如这里眼见循环只有一次,但是取值的结果有那么多种
第三点、list+【,】是直接对数组进行操作的,比append不知道高到哪里去了。
这么多的可能都是在递归的过程中,形成循环的嵌套,这样来实现的。
所以这函数转换成伪代码的话
函数solve()
if 现有和大于目标,不再继续递归
if 和等于目标,输出
否则 继续递归
这里的目标goal是在递减,佐证就是跟list【i】比较
跟sum比较就是没理解对。
递归的三个点
1 所求的变化中的结果
2 递归的参数
3 递归结束的标志
比如阶乘
结果是乘积,参数是数字n(1~n),结束标志是n =1
if n==1:
return 1
return n*fuc(n-1)
比如数组中m个数的和
结果是数字的集合,参数是数组下标,结束标志是goal-之前的数字=现在的数字
—>和等于目标值goal,总体的值转换成单个的值 ,和=goal—>goal-之前的数字=现在的数字
这里还嵌套了一个for循环,之前阶乘的循环过程是n,n-1,n-2,是隐式的。
这里过程是取c[1],取c[2],不取c[3]等,所以不是线性,需要循环。
for i in range(len©):
if c[i] = goal
return 结果的集合
return fuc(c[i+1:],goal)