Присвоение значения переменной Python в рекурсии

1

Существует два решения проблемы:

Проблема заключается в следующем:

Введите корневой узел двоичного дерева и целое число, чтобы распечатать путь, где сумма значений узлов в двоичном дереве является целым числом ввода. Путь определяется как путь от корневого узла дерева до следующего узла до тех пор, пока листовой узел не пройдет. (Примечание: в списке возвращаемых значений впереди находится массив с наибольшей длиной массива)

решение одно

# 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 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 в рекурсии !!!

  • 0
    Попробуйте выполнить трассировку через выполнение - в отладчике или в визуализаторе, таком как PythonTutor, или добавив print s, или просто на бумаге, чтобы вы могли видеть, какие вызовы сделаны, и какой path в каждой точке. Если вы не можете сделать это, никакое объяснение не будет иметь смысла; если вы можете сделать это, вы на 90% сможете ответить на него сами.
  • 0
    @abarnert Я знаю, как отлаживать, и я знал, как список изменяется в рекурсии, но дело в том, что я не знаю, почему, и я хочу знать, почему
Показать ещё 1 комментарий
Теги:
recursion
variables
binary-tree
variable-assignment

2 ответа

0

Вы можете упростить свой рекурсивный метод несколькими способами. Во-первых, на каждой итерации проверьте, соответствует ли значение узла, переданному методу, сумме текущего содержимого пути меньше или равно требуемому значению. Во-вторых, если последнее меньше, вызовите метод слева и справа от дерева:

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]]]
  • 0
    Спасибо за ответ, но вы не отвечаете на мой вопрос: «почему в решении 1 список путей не нуждается в операции pop, а в решении 2. Другими словами, почему решение 1 не разделяет список путей, а решение 2 делает Кстати, ваш код прекрасен!
0

Я нахожу, что ваш код имеет много ошибок, которые затрудняют отслеживание:

**** Во-первых: любой def или function внутри любого класса Python должен быть нижним регистром с подчеркиванием, поэтому мы можем выяснить, что является классом из функции, поэтому ваш 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

это совершенно неверно, вы назначаете значение None для preassaigned value в isleaf, и вы снова передаете переменную isleaf (и) слово так, как логическую или питоновую логику: как будет понимать isleaf для получения двух значений (root.left и root.right), которые получают значения None, не имеет никакого смысла. поэтому, пожалуйста, дайте нам представление о том, что именно вы хотите сделать здесь.

**** Четвертое: подумайте, чтобы дать один пробел после и перед любым оператором, а вместо "if path_sum

**** Не бойтесь давать переменные или аргументы реальным именам, чтобы выявить реальные потребности в нем или, по крайней мере, попытаться дать комментарий для него, например, например: что делает t = [] !!! !!!!

Поэтому, пожалуйста, постарайтесь быть более конкретными, чтобы вы могли найти хорошую помощь для своих проблем и сделать свой код более питоническим.


Новое редактирование:

В решении нет 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(), который удалит последний "root", добавленный в список путей:

path.pop()

и затем он вызывает следующую строку, которая снова вызовет функцию поиска

find(root,path,path_sum)

но на этот раз назовем это пустым значением пути, ПОЧЕМУ? потому что первый объект списка пути "путь = []" находится на той же самой области, что и вызов последней функции поиска "find (root, path, path_sum)", поэтому внутренний аргумент пути и значения, которые не видны внешним путем scope, они видны только функцией find().

И этот объем вопросов точно так же относится к "Решение 1", за исключением того, что вы передаете список путей с корневым значением, и когда это условие является ложным

if path_sum<expectNumber:

код снова вызовет функцию find(), но с путём, имеющим только корневое значение в первом объявлении "путь = [корень]".

И после всего, что я думаю с уважением, вы не делите весь код на проблему конфиденциальности, так что трудно легко найти ответ.

  • 0
    Это проблема из китайского кода веб-сети крупного рогатого скота nowcoder.com/practice / ...
  • 0
    isleaf = root.left == Нет и root.right == Нет. Это означает логический результат: isleaf is bool
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню