简体   繁体   English

为什么我的递归方法在 Python 中不起作用?

[英]Why doesn't my recursive approach work in Python?

I've been racking my brain trying to figure out why these two approaches in solving a Leetcode problem ( Combination Sum ), despite looking virtually the same.尽管看起来几乎相同,但我一直在绞尽脑汁想弄清楚为什么这两种方法可以解决 Leetcode 问题(组合求和)。 The first approach (working) takes in extra parameters that do not appear to be necessary.第一种方法(工作)采用似乎不必要的额外参数。 I have checked my code with print statements, and subsets with the required total are found, but for some reason, the result is not properly appended to res .我已经用打印语句检查了我的代码,并找到了所需总数的子集,但由于某种原因,结果没有正确附加到res Instead of appending the valid subset, it appends an empty list.它不是附加有效的子集,而是附加一个空列表。 I'm sure the answer is simple, but I cannot seem to find the logical difference.我确信答案很简单,但我似乎无法找到逻辑上的区别。 Here's both methods:这里有两种方法:

def combinationSumWorking(candidates, target):
    result = []
    def combinationUtil(index, numbers, sumSoFar):
        if sumSoFar > target:
            return
        if sumSoFar == target:
            #print("working",numbers)
            result.append(numbers)
            return
        for i in range(len(candidates)):
            combinationUtil(i, numbers+[candidates[i]], sumSoFar+candidates[i])
    
    combinationUtil(0,[],0)
    return result

def combinationSumMine(candidates, target):
    res = []
    def findCombos(subset):
        if(sum(subset) > target):
            subset = []
            return
        if(sum(subset) == target):
            res.append(subset)
            #print("mine",subset)
            subset = []
            return
        for i in range(len(candidates)):
            subset.append(candidates[i])
            findCombos(subset)
            subset.pop()
    findCombos([])
    return res
    
print(combinationSumMine([2,3,6,7],7))
print(combinationSumWorking([2,3,6,7],7))
        

The result is:结果是:

[[], [], [], []]
[[2, 2, 3], [2, 3, 2], [3, 2, 2], [7]]

Your problem is doing the append, then the recursive call, and then popping.你的问题是做追加,然后递归调用,然后弹出。 I'll explain in a second.我马上解释。 Here's a version of your code that gets your expected result:这是获得预期结果的代码版本:

def combinationSumMine(candidates, target):
res = []
def findCombos(subset):
    if(sum(subset) > target):
        return
    if(sum(subset) == target):
        res.append(subset)
        return
    for i in range(len(candidates)):
        findCombos(subset + [candidates[i]] )
        
findCombos([])
return res

print(combinationSumMine([2,3,6,7],7))

What's happening is, you iterate through the list of candidates appending a new value to your subset list and then you make the recursive call.发生的事情是,您遍历候选列表,将新值附加到您的子集列表,然后进行递归调用。 So, when that recursive call executes it's executing with the list you already added one of the candidates to.因此,当该递归调用执行时,它会使用您已将其中一个候选者添加到的列表执行。 Likewise, when, or if, you find a result, you append the same "subset" list to your result.同样,当您找到结果时,或者如果您找到结果,则将相同的“子集”列表附加到您的结果中。 When you "pop" a value off, you're popping it off the subset that's in your result.当您“弹出”一个值时,就是从结果中的子集中弹出它。 That's why you'll always return an empty answer.这就是为什么你总是会返回一个空的答案。

What you want to do instead is create a copy of the subset list.您想要做的是创建子集列表的副本。 One way to do that, in my example, is, instead of providing the subset list to the findCombos function I supply the result of concatenating the subset list to a list containing the new element we want to consider.在我的示例中,这样做的一种方法是,不是向 findCombos 函数提供子集列表,而是提供将子集列表连接到包含我们要考虑的新元素的列表的结果。 That's an entirely new list!这是一个全新的清单!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM