Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
递归中的Python变量值赋值_Python_Variables_Recursion_Binary Tree_Variable Assignment - Fatal编程技术网

递归中的Python变量值赋值

递归中的Python变量值赋值,python,variables,recursion,binary-tree,variable-assignment,Python,Variables,Recursion,Binary Tree,Variable Assignment,一个问题有两种解决方案: 问题是: 输入二叉树的根节点和一个整数以打印出路径,其中二叉树中的节点值之和为输入整数。路径定义为从树的根节点到下一个节点的路径,直到叶节点通过。(注意:在返回值列表中,数组长度最大的数组在前面) 解决方案一 # class TreeNode: # def __init__(self, x): # self.val = x # self.left = None # self.right = None class S

一个问题有两种解决方案:

问题是:

输入二叉树的根节点和一个整数以打印出路径,其中二叉树中的节点值之和为输入整数。路径定义为从树的根节点到下一个节点的路径,直到叶节点通过。(注意:在返回值列表中,数组长度最大的数组在前面)

解决方案一

# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None
class Solution:
    def FindPath(self, root, expectNumber):
        if not root:
            return []
        result=[]
        path=[root]
        path_sum=0
        def find(root,path,path_sum):
            isleaf= root.left==None and root.right==None  # a bool,whether is leaf node

            path_sum+=root.val
            if isleaf and path_sum==expectNumber:
                t=[]
                for i in path:
                    t.append(i.val)
                result.append(t) # add a appropriate path's value to result
            if path_sum<expectNumber:
                if root.left:

                    find(root.left,path+[root.left],path_sum)#note!!!!!
                if root.right:

                    find(root.right,path+[root.right],path_sum)#note!!!!!

        find(root,path,path_sum)
        return result
#类树节点:
#定义初始化(self,x):
#self.val=x
#self.left=无
#self.right=无
类解决方案:
def FindPath(self、root、expectNumber):
如果不是根目录:
返回[]
结果=[]
路径=[根]
路径总和=0
def find(根、路径、路径和):

isleaf=root.left==None和root.right==None#一个布尔值,是否为叶节点 路径_sum+=root.val 如果isleaf和path_sum==expectNumber: t=[] 对于路径中的i: t、 附加(i.val) result.append(t)#将适当路径的值添加到结果中
如果path_sum我发现您的代码有很多错误,很难跟踪:

****首先:任何Python类中的任何def或函数都应该是带下划线的小写,这样我们就可以从函数中找出什么是类,所以FindPath()应该是>>>>>find_path()

****第二:如果你想在一个类的全局范围内声明任何参数,你应该在一个函数中作为构造函数或初始值设定项来声明,所以你的E.G代码应该是:

class Solution:
    def __init__(self, root, expect_number):
        self.root = root
        self.expect_number = expect_number
无论何时调用类内的任何参数,都应该使用(self.arg)调用它,例如self.root

****第三:这句话根本不可理解:

def find(root,path,path_sum):
            isleaf= root.left==None and root.right==None
这是完全错误的,您将None值分配给isleaf的预赋值值,并且再次给isleaf变量一个(and)字,作为逻辑或pythonic逻辑:isleaf如何理解获得None值的两个值(root.left和root.right),没有任何意义。 所以请告诉我们你到底想在这里做什么

****第四:考虑在任何操作符之后和之前给予一个空间,而不是 “如果路径_和 ****不要害怕给变量或参数取一个真实的名字来讨论它的真正需求,或者至少试着给它一个注释,例如:t=[]在做什么

因此,请尝试更具体一些,这样您就可以为您的问题找到很好的帮助,并使您的代码更具python风格


新编辑:

在解决方案2中:每次调用find()函数时,都会将“root”值追加或添加到路径列表中

    def find(root,path,path_sum):
        isleaf= root.left==None and root.right==None
        path.append(root) # here you added the root to the path
直到这个条件为false,代码仍然是递归的:

if path_sum<expectNumber: 
然后它调用下一行,这将再次调用find函数

find(root,path,path_sum)
但这次会用空路径值调用它,为什么? 因为第一个路径列表对象“path=[]”与作用域处于同一级别 调用最后一个find函数“find(root、path、path_sum)” 因此,内部路径参数和它的值不被外部路径范围看到,它们只被find()函数本身看到

这个作用域的问题与“解决方案1”的问题完全相同,只是传递了一个带有根值的路径列表,并且当这个条件为False时

if path_sum<expectNumber:

if path_sum您可以通过几种方式简化递归方法。首先,在每次迭代中,检查传递给该方法的节点值以及当前路径内容的总和是否小于或等于所需值。其次,如果后者较小,则调用树左右两侧的方法:

class Solution:
  @classmethod
  def find_path(cls, head, val:int, current = []):
    if sum(current) == val:
       yield current
    elif head.value+sum(current) < val:
      if head.left is not None:
        yield from cls.find_path(head.left, val, current+[head.value])
      if head.right is not None:
        yield from cls.find_path(head.right, val, current+[head.value])
    elif head.value+sum(current) == val:
      yield current+[head.value]
输出:

[[[10, 2]], [[10, 2, 2]], [[10, 8, 5]]]

尝试跟踪执行过程——在调试器中,或者在Pythonutor这样的可视化工具中,或者通过添加
print
s,或者仅仅在纸上,这样你就可以看到调用的内容,以及每个点的
path
是什么。如果你做不到,任何解释都没有意义;如果你能做到,你自己就有90%的回答方法了。@aba我不知道如何调试,我也知道递归中列表是如何变化的,但问题是我不知道为什么,我想知道why@abarnert“打什么电话”是什么意思?你能从中文代码网解释一下这是个问题吗牛客网 isleaf=root.left==None和root.right==None这意味着一个逻辑结果:isleaf是boolmy的问题不是关于类的变量,我关心的是递归中的变量值赋值。您可以将该类想象为两个函数感谢anser,但您没有回答我的问题:“为什么在解决方案1中路径列表不需要pop操作,而解决方案2需要pop操作?”。换句话说,为什么解决方案1不共享路径列表,而解决方案2却共享“顺便说一句,您的代码很漂亮!
class Solution:
  @classmethod
  def find_path(cls, head, val:int, current = []):
    if sum(current) == val:
       yield current
    elif head.value+sum(current) < val:
      if head.left is not None:
        yield from cls.find_path(head.left, val, current+[head.value])
      if head.right is not None:
        yield from cls.find_path(head.right, val, current+[head.value])
    elif head.value+sum(current) == val:
      yield current+[head.value]
class Tree:
  def __init__(self, **kwargs):
    self.__dict__ = {i:kwargs.get(i) for i in ['left', 'right', 'value']}

t = Tree(value=10, left=Tree(value=8, left=Tree(value=3), right=Tree(value=5)), right=Tree(value=2, left=Tree(value=2)))

""" 
     10
   /    \
  8      2
 / \    /
3   5  2
"""
results = [list(Solution.find_path(t, i)) for i in [12, 14, 23]]
[[[10, 2]], [[10, 2, 2]], [[10, 8, 5]]]