我一直在寻找这个问题的解决方案(下面)几个小时,并且无法弄清楚递归是如何工作的。有人可以用基本的术语解释它是如何工作的。
由于组被追加然后弹出,弹出列表是不是总是等于没有[]?
# Given a list of ints, is it possible to choose a group of some of the
# ints, such that the group sums to the given target?
# 0, 2, 4, 8, 10 -> True
# 0, 2, 4, 8, 14 -> True
# 0, 2, 4, 8, 9 -> False
def sum_checker(ints, total, group, index):
if sum(group) > total: # backtracking
return False
if index == len(ints): # BASE CASE
return sum(group) == total
group.append(ints[index])
if sum_checker(ints, total, group, index + 1):
return True
group.pop()
return sum_checker(ints, total, group, index + 1)
ints = [int(input()) for i in range(int(input()))]
total = int(input())
group = []
print(sum_checker(ints, total, group, 0))
答案 0 :(得分:1)
确定。所以,让我们首先考虑这个没有真正代码的问题。试想这个策略:
ints
的每个元素,通过选择当前值和先前的选择进行检查,我们可以获得目标总和。 ints= [1, 2, 4, 8]
,target = 11
。1
,我们不知道在检查其他元素之前是否可以获得目标,因此我们会继续检查,并将1
放在您手中。2
,仍然不知道,只需选择并继续。4
相同。sum=1+2+4+8 = 13 > 11
。 [1,2,4,8]是一个糟糕的选择计划。如果我们有其他选择,让我们从最后退出并且谢谢。删除8
。sum=1+2+4=7
,但我们无法添加更多元素,因为我们到达ints
的末尾。删除4
以查看是否有更多选择。1+2
,应该从8
查看11
!我们做到了!因此,请使用铅笔和纸张自己尝试这个过程。这里的核心思想是维护一个我们已选择的数组,在您的代码中为group
,然后检查是否可以基于此来达到目标选择+新元素。如果没有,请修改我们已选择的数组并继续。
答案 1 :(得分:1)
不是弹出列表总是等于没有[]?
并非总是如此。在第三个if语句中,它递归地添加到组列表中,并且仅当该调用堆栈返回时(当组的总和超过总数,或者索引超出输入范围时),最近推送的值是否会弹出。
在第一个输入的执行顺序中,这是组值
0
0, 2
0, 2, 4
0, 2, 4, 8... Sum is greater than 10, return False
8 is popped, and the previous index increases
0, 2, 4.... The index is out of range, and the group sum is not the total
4 is popped and the previous index increases
0, 2, 8... This is equal to 10, so we return True back up the call stack
在展开递归结束时,是的,组列表将为空,但输出只需要一个布尔值,而不是跟踪符合条件的组
答案 2 :(得分:1)
关于您group
被追加和弹出的问题。请记住声明
if sum_checker(ints, total, group, index + 1):
再次开始搜索(这次是下一个索引)。跟你的例子说。
sum_checker(
ints=[0, 2, 4, 8],
total=10,
group=[],
index=0
)
我们第一次点击群组时,会将0
追加到group
,因此我们会使用参数调用sum_checker
。
sum_checker(
ints=[0, 2, 4, 8],
total=10,
group=[0],
index=1
)
然后,由于group
已有一个元素,我们会将2
追加到group
。所以我们有:
sum_checker(
ints=[0, 2, 4, 8],
total=10,
group=[0, 2],
index=2
)
这意味着,在我们到达group
之前,我们开始填写.pop()
。如果sum()
的{{1}}变得过大,那么我们会执行第一个group
,并在没有添加最后一个元素的情况下再次开始检查。