Существует два решения проблемы:
Проблема заключается в следующем:
Введите корневой узел двоичного дерева и целое число, чтобы распечатать путь, где сумма значений узлов в двоичном дереве является целым числом ввода. Путь определяется как путь от корневого узла дерева до следующего узла до тех пор, пока листовой узел не пройдет. (Примечание: в списке возвращаемых значений впереди находится массив с наибольшей длиной массива)
решение одно
# 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 в рекурсии !!!
Вы можете упростить свой рекурсивный метод несколькими способами. Во-первых, на каждой итерации проверьте, соответствует ли значение узла, переданному методу, сумме текущего содержимого пути меньше или равно требуемому значению. Во-вторых, если последнее меньше, вызовите метод слева и справа от дерева:
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]]]
Я нахожу, что ваш код имеет много ошибок, которые затрудняют отслеживание:
**** Во-первых: любой 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(), но с путём, имеющим только корневое значение в первом объявлении "путь = [корень]".
И после всего, что я думаю с уважением, вы не делите весь код на проблему конфиденциальности, так что трудно легко найти ответ.
print
s, или просто на бумаге, чтобы вы могли видеть, какие вызовы сделаны, и какойpath
в каждой точке. Если вы не можете сделать это, никакое объяснение не будет иметь смысла; если вы можете сделать это, вы на 90% сможете ответить на него сами.