【问题标题】:Updating variables in recursion递归更新变量
【发布时间】:2020-04-28 17:32:15
【问题描述】:

这里指的是这个leetcode问题:https://leetcode.com/problems/path-sum-iii/

基本上我得到一个二叉树,其中每个节点都包含一个整数值。我必须找到总和为给定值的路径数。

在这里建立一个示例树

class TreeNode:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

root = TreeNode(12)
root.left = TreeNode(7)
root.right = TreeNode(1)
root.left.left = TreeNode(4)

root.right.left = TreeNode(10)
root.right.right = TreeNode(5)

这是我使用递归的解决方案

def count_paths(root, S):

    cache = {0:1}

    def helper(node, S:int, curr_path:int, cache:dict, result:int):

        if not node:
            return result

        curr_path += node.val
        prev_path = curr_path - S

        result += cache.get(prev_path, 0)
        cache[curr_path] = cache.get(curr_path, 0) + 1

        my_node = None
        if node != None:
            my_node = node.val 

        print("node: {}, curr: {}, prev: {}".format(my_node, curr_path, prev_path))                
        print(cache)
        print(result)

        helper(node.left, S, curr_path, cache, result)
        helper(node.right, S, curr_path, cache, result)

        return result

    return helper(root, S, 0, cache, 0)

基本上我不明白为什么递归函数没有更新我的 result 变量,而是更新了我的 cache 变量。

是否有更新结果变量的正确方法?

这是测试用例

count_paths(root, 11)

我打印了每一行结果

node: 12, curr: 12, prev: 1
{0: 1, 12: 1}
0
node: 7, curr: 19, prev: 8
{0: 1, 12: 1, 19: 1}
0
node: 4, curr: 23, prev: 12
{0: 1, 12: 1, 19: 1, 23: 1}
1
node: 1, curr: 13, prev: 2
{0: 1, 12: 1, 19: 1, 23: 1, 13: 1}
0
node: 10, curr: 23, prev: 12
{0: 1, 12: 1, 19: 1, 23: 2, 13: 1}
1
node: 5, curr: 18, prev: 7
{0: 1, 12: 1, 19: 1, 23: 2, 13: 1, 18: 1}
0
Tree has paths: 0

有人可以解释一下我在这里缺少什么吗?我有一种感觉,我在这里犯了一个基本的递归错误。我知道我创建了一个类并将变量存储在那里,但我真的很了解如何正确地进行递归。非常感谢!

【问题讨论】:

  • 因为你没有改变cache(也就是说,它仍然是同一个对象),你改变的是in @987654327 @.
  • @ScottHunter 感谢您的澄清!有没有办法更新结果变量?
  • 我不相信有办法更新int。如果你把它放在某种容器中(比如dict),那么你可以像缓存一样更新它。
  • 好的,谢谢!

标签: python recursion tree binary-search-tree breadth-first-search


【解决方案1】:

tldr:

Python 默认是通过引用传递的,但是由于整数是不可变的,它就像那些通过复制传递一样。这里最简单的解决方法是result += helper(...), or result = helper(...)

长答案:

在许多语言(如 C++ 和 Java)中,传递参数默认为传递这些对象的副本。如果您想将一个对象传递给一个函数并对其进行更新以在该函数的上下文之外使用,您必须传递一个指针(或类似的东西)。

另一方面,Python 默认通过引用传递。这会让您认为您的 result 变量会更新到位,对吧?

问题是result,作为一个整数,是不可变的。因此,当您在其中一个递归调用中更改其值时,它不会更改其他调用的 result 变量。它只是将标签result 重新分配给一个新的整数值,但仅限于该函数调用的范围内。一旦函数返回,新值就会丢失。

如果您想通过函数调用更新整数变量的值,您必须将变量设置为函数的返回值(参见上面的 tldr),或者将整数包装在可变对象中(参见Passing an integer by reference in Python )。

【讨论】:

    猜你喜欢
    • 2021-04-09
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-25
    • 2020-09-05
    • 2012-03-17
    相关资源
    最近更新 更多