递归中的Python变量值分配

时间:2018-08-25 08:10:21

标签: python variables recursion binary-tree variable-assignment

有两种解决方法:

问题是:

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

解决方案一

# 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

解决方案2

class Solution:
    def FindPath(self, root, expectNumber):
        if not root:
            return []
        result=[]
        path=[]
        path_sum=0
        def find(root,path,path_sum):
            isleaf= root.left==None and root.right==None
            path.append(root)#note!!!!!
            path_sum+=root.val
            if isleaf and path_sum==expectNumber:
                t=[]
                for i in path:
                    t.append(i.val)
                result.append(t)
            if path_sum<expectNumber:
                if root.left:
                    find(root.left,path,path_sum)
                if root.right:
                    find(root.right,path,path_sum)
            path.pop()#note!!!!!
        find(root,path,path_sum)
        return result

我不知道为什么在解决方案1中,路径列表不需要弹出操作,但是解决方案2需要。换句话说,为什么解决方案1不共享路径列表,而解决方案2却共享路径列表。

请帮助我,我找不到这样的纸弄明白我!

我的意思不是关于类,您也可以使用函数来解决此问题。

我在乎的是Python 递归中的变量值分配 !!!!

2 个答案:

答案 0 :(得分:0)

我发现您的代码有很多错误,将使其难以跟踪:

****首先:任何Python类中的任何def或函数都应使用小写并带有下划线,因此我们可以从函数中找出什么是类,因此您的FindPath()应该为>>>>>> find_path ()

****第二:如果您要声明某个类的全局范围的任何参数,则应在函数内作为构造函数或初始化程序进行此操作,因此EG的代码应为:

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

这是完全错误的,您要向isleaf的预先确定的值分配None值,然后再次给isleaf变量一个(和)一个单词,作为逻辑或pythonic逻辑:isleaf将如何理解以获取两个获得None值的值(root.left和root.right)没有任何意义。 因此,请给我们一个关于您到底想在这里做什么的想法。

****第四:考虑在任何运算符的前面和后面给一个空格,而不是  “如果path_sum

****不要害怕给变量或参数起实名来区别其实际需求,或者至少尝试对其进行注释,例如:t =什么是t = []在做!!!!!!!

因此,请尝试更具体一些,以便为您的问题找到良好的帮助,并使您的代码更具pythonic性。


新编辑:

在解决方案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

,并且在此条件为假之前,代码仍然是递归的:

if path_sum<expectNumber: 

,当它为false时,它将开始调用pop()方法,该方法将删除 最后一个“根”,添加到路径列表中:

path.pop()

然后调用下一行,这将再次调用find函数

find(root,path,path_sum)

但是这次将使用空路径值调用它,为什么? 因为第一个路径列表对象“ path = []”的作用域与 最后一个查找函数“ find(root,path,path_sum)”的调用 因此,内部路径参数及其值不会在外部路径范围内看到,而只能由它自己的find()函数看到。

此作用域与“解决方案1”完全相同,所不同的是,您传递的是带有根值的路径列表,并且当此条件为False时

if path_sum<expectNumber:

代码将再次调用find()函数,但路径仅在第一个公告“ path = [root]”中具有根值。

毕竟,我认为您不会共享有关隐私问题的完整代码,因此很难轻松找到答案。

答案 1 :(得分:0)

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

.add

用于演示的树类:

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]]