【问题标题】:How to check whether the sum exists for a given path in a tree如何检查树中给定路径的总和是否存在
【发布时间】:2016-10-12 15:09:32
【问题描述】:

我想检查从起始节点到任何路径中的值的总和

叶节点存在。

例如,假设我的 startNode 是 7,而 sumTarget 是 15,如果树是:

        a-7
  b - 1    e- 8
  c - 2    
  d -9 

那么由于 7 +8 等于 15 它会返回 true

如果我有 b 作为 startNode,12 作为 sumTotal,那么它也会返回 true,因为 1 +2 + 9 是 12,从 b 开始。

class Node {
    int value;
    Node [] children
}

我不认为这是对的,但我不确定哪里错了。

def doesSumExist(startNode, sumTarget, currentSum):
    totalSum = sumTarget
    if startNode is not Null:
        if totalSum + startNode.value == sumTarget:
            return True
        else:
            totalSum += startNode.value
    else:
        Node startNode = doesSumExist(startNode.left, sumTarget, currentSum)  
        if startNode is not Null:
            return currentSum
        startNode = doesSumExist(startNode.right, sumTarget,currentSum)
    return False

【问题讨论】:

  • 什么是startNode.left和startNode.right?孩子们?您没有检查递归调用的返回值。您需要传递参数 currentSum 而不是每次都擦除 sumTarget。您不想检查是否 totalSum == startNode.value。您想检查是否 totalSum+startNode.value == sumTarget。您不想分配 totalSum = sumTarget。您想传递一个名为 currentSum 的参数(如我之前所说)。这个递归函数需要 3 个参数。如果您向我解释您使用的结构,我将能够更好地帮助您。
  • 是的 startNode.left 和 startNode.right 是孩子。我编辑了帖子以包含示例树和数字,并且还根据您的建议修改了代码。谢谢你的帮助。 else: totalSum += startNode.value 应该改为 totalSum+= startNode.left 还是 startNode.right?

标签: python data-structures binary-tree


【解决方案1】:

在这种情况下,我认为您要搜索的内容类似于以下内容:

def doesSumExist(startNode, sumTarget, currentSum):
    totalSum = currentSum
    if startNode is not Null:
        if totalSum + startNode.value == sumTarget: #If this node completes the sum
            return True
        else: #if not
            totalSum += startNode.value #increase current sum
    if doesSumExist(startNode.left, sumTarget, totalSum): #recursive starting on the left children
        return True
    elif doesSumExist(startNode.right, sumTarget, totalSum): #recursive starting on the right children
        return True           
    return False #if the sum is not present (starting in startNode).

但是,这不会检查任何连续的节点组合是否包含总和(代码会复杂得多)。

希望对你有帮助

【讨论】:

  • 谢谢。是的,我真的想看看你说的不仅是两个节点,而且是三个或更多节点是否包含总和。我将自己更多地工作以使其正常工作。感谢您的帮助!
  • 我放置的代码适用于任何给定数量的连续节点。但是,如果你在树中有总和,但如果你从 startNode 开始它不存在,它就不会找到它。想象一下你的树,如果你做 dosSumExist(a, 12, 0) 它不会找到它,因为总和从 b 开始,而不是 a。明白了吗?
  • 如果它以 b 开头,它将是 (b, 12, 0) 我将修改代码以使该情况也能正常工作。但我可能需要多次尝试才能做到这一点。但是,一旦我走得更远,我会回帖。再次感谢!
  • 如果它以 b 开头,它也会找到它,我想我没有正确解释自己。考虑到它将始终从 startNode 开始(无论您传递给函数的节点是什么),它会在路径中找到任何现有的总和。但是,如果总和存在于树中,但它从更下方开始,则不会被验证。在您的示例中,如果您从 b 开始,则树包含总和 12。但是如果你调用函数 dosSumExist(a, 12, 0) 它会说它没有,因为它会包含来自 a 的值 9。
【解决方案2】:

假设你的节点类看起来像这样:

class Node:
    def __init__(self, value = 0, children = None):
        self.value = value
        self.children = [] if children is None else children

那么这个方法应该可以解决问题:

def doesSumExist(startNode, targetSum, currentSum):
    if startNode is None:
        return False
    currentSum += startNode.value
    if currentSum == targetSum:
        return True
    for child in startNode.children:
        if doesSumExist(child, targetSum, currentSum):
            return True
    return False

请注意,对于这个节点类设计,startNode 的无检查对于递归来说并不是真正必要的,而只是对于入口点而言。所以这可能会更好:

def doesSumExist(startNode, targetSum):
    def inner(node, targetSum, currentSum):
        currentSum += node.value
        if currentSum == targetSum:
            return True
        #for people who like to save a few lines
        #return any(inner(child, targetSum, currentSum) for child in node.children)
        for child in node.children:
            if inner(child, targetSum, currentSum):
                return True
        return False

    if startNode is None:
        return False
    return inner(startNode, targetSum, 0)

编辑: 如果您不仅想知道总和是否存在于起始节点的路径中,而且还想知道它是否存在于任何给定的子路径中,这应该可行:

def doesSumExist(startNode, targetSum):
    def inner(node, targetSum, allValues):
        allValues.append(node.value)
        currentSum = 0
        for val in reversed(allValues):
            currentSum += val
            if currentSum == targetSum:
                return True
        for child in node.children:
            if inner(child, targetSum, allValues):
                return True
        allValues.pop()
        return False

    if startNode is None:
        return False
    return inner(startNode, targetSum, [])

【讨论】:

  • 谢谢。我会试试这个!
  • 不客气,希望对您有所帮助。但是,这也不适用于在子路径中查找总和,如下所述。我用另一个应该适用的版本编辑了我的帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-18
相关资源
最近更新 更多