我现在正在研究DFS方法来计算路径的总和。问题陈述是:
给定一棵二叉树和一个数字“S”,找到树中的所有路径,使每条路径的所有节点值之和等于“S”。请注意,路径可以在任何节点开始或结束,但所有路径必须遵循从父节点到子节点(从上到下)的方向。
我的做法是:
def all_sum_path(root, target):
global count
count = 0
find_sum_path(root, target, [])
return count
def find_sum_path(root, target, allPath):
global count
if not root:
return 0
# add a space for current node
allPath.append(0)
# add current node values to all path
allPath = [i+root.value for i in allPath]
print(allPath)
# check if current path == target
for j in allPath:
if j == target:
count += 1
# recursive
find_sum_path(root.left, target, allPath)
find_sum_path(root.right, target, allPath)
# remove the current path
print('after', allPath)
allPath.pop()
print('after pop', allPath)
class TreeNode():
def __init__(self, _value):
self.value = _value
self.left, self.right, self.next = None, None, None
def main():
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)
print(all_sum_path(root, 11))
main()
带返回:
[1]
[8, 7]
[14, 13, 6]
after [14, 13, 6]
after pop [14, 13]
[13, 12, 5, 5]
after [13, 12, 5, 5]
after pop [13, 12, 5]
after [8, 7, 0, 0]
after pop [8, 7, 0]
[10, 9, 9]
[12, 11, 11, 2]
after [12, 11, 11, 2]
after pop [12, 11, 11]
[13, 12, 12, 3, 3]
after [13, 12, 12, 3, 3]
after pop [13, 12, 12, 3]
after [10, 9, 9, 0, 0]
after pop [10, 9, 9, 0]
after [1, 0, 0]
after pop [1, 0]
4
我认为问题在于我没有成功删除列表中最右边的节点。然后我更新了我的代码如下,删除了allPath
最右边的节点,并创建了一个名为newAllPath
的新列表来记录已经加上当前节点值的节点。
def all_sum_path(root, target):
global count
count = 0
find_sum_path(root, target, [])
return count
def find_sum_path(root, target, allPath):
global count
if not root:
return 0
# add a space for current node
allPath.append(0)
# add current node values to all path
newAllPath = [i+root.value for i in allPath]
print(allPath, newAllPath)
# check if current path == target
for j in newAllPath:
if j == target:
count += 1
# recursive
find_sum_path(root.left, target, newAllPath)
find_sum_path(root.right, target, newAllPath)
# remove the current path
print('after', allPath, newAllPath)
allPath.pop()
print('after pop', allPath, newAllPath)
class TreeNode():
def __init__(self, _value):
self.value = _value
self.left, self.right, self.next = None, None, None
def main():
root = TreeNode(1)
root.left = TreeNode(7)
root.right = TreeNode(9)
root.left.left = TreeNode(6)
root.left.right = TreeNode(5)
root.right.left = TreeNode(2)
root.right.right = TreeNode(3)
print(all_sum_path(root, 12))
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)
print(all_sum_path(root, 11))
main()
带返回:
[0] [1]
[1, 0] [8, 7]
[8, 7, 0] [14, 13, 6]
after [8, 7, 0] [14, 13, 6]
after pop [8, 7] [14, 13, 6]
[8, 7, 0] [13, 12, 5]
after [8, 7, 0] [13, 12, 5]
after pop [8, 7] [13, 12, 5]
after [1, 0] [8, 7]
after pop [1] [8, 7]
[1, 0] [10, 9]
[10, 9, 0] [12, 11, 2]
after [10, 9, 0] [12, 11, 2]
after pop [10, 9] [12, 11, 2]
[10, 9, 0] [13, 12, 3]
after [10, 9, 0] [13, 12, 3]
after pop [10, 9] [13, 12, 3]
after [1, 0] [10, 9]
after pop [1] [10, 9]
after [0] [1]
after pop [] [1]
3
我不确定为什么在第一种方法中无法成功删除最右边的节点。然而,在我的第二种方法中,一旦我删除了allPath
中最右边的节点,它也会删除newAllPath
中的节点。
谢谢你的帮助。我很困惑,一整天都被困在这里。
功能原理
这是一个非常重要的问题,我不会尝试调试您的程序,因为它违背了递归的使用方式。重申一下,递归是一种函数遗产,因此将其与函数风格结合使用会产生最好的结果。这意味着避免-
. append
,=1
,. pop
左=...
,右=...
,allPath=...
计数
print
分解
试图将任务的所有关注点打包到一个函数中是个坏主意。把问题分解成不同的部分有很多好处-
首先,我们将使用我们在之前的Q中已经写过的find_sum
def find_sum(t, q, path = []):
if not t:
return
elif t.value == q:
yield [*path, t.value]
else:
yield from find_sum(t.left, q - t.value, [*path, t.value])
yield from find_sum(t.right, q - t.value, [*path, t.value])
使用find_sum
我们可以轻松编写all_sum
-
def all_sum(t, q):
for n in traverse(t):
yield from find_sum(n, q)
这需要我们编写一个通用的遍历
-
def traverse(t):
if not t:
return
else:
yield from traverse(t.left)
yield t
yield from traverse(t.right)
让我们看看它在样本树上的工作情况-
12
/ \
/ \
7 1
/ \ / \
4 3 10 5
/ /
1 1
我们使用您的TreeNode
构造函数来表示它-
t1 = TreeNode \
( 12
, TreeNode(7, TreeNode(4), TreeNode(3, TreeNode(1)))
, TreeNode(1, TreeNode(10, TreeNode(1)), TreeNode(5))
)
print(list(all_sum(t1, 11)))
[[7, 4], [7, 3, 1], [10, 1], [1, 10]]
计算所有的金额
如果唯一的目标是计算总和,我们可以编写count_all_sum
作为all_sum
-
def count_all_sum (t, q):
return len(list(all_sum(t, q)))
除非你的树深度超过1000个节点,否则你可以使用递归来获得更简单的代码:
def findSums(node,target):
if not node : return
if node.value == target: yield [node.value] # target reached, return path
for child in (node.left,node.right): # traverse tree DFS
yield from findSums(child,target) # paths skipping this node
for subPath in findSums(child,target-node.value): # paths with remainder
yield [node.value]+subPath # value + sub-path
for sp in findSums(root,11):
print(sp)
# [7, 4]
# [1, 10]
要打印二叉树,请参阅以下内容:https://stackoverflow.com/a/49844237/5237560
我正在学习数据结构,并试图理解Java中的链接列表。我的问题是,我有麻烦与删除节点在给定的索引递归。我的目标是得到O(log n),而不是使用循环,最后得到O(n)。 因此,当我试图删除索引2的条目时,它会删除该索引之前的所有数字,但不会删除该索引-因此它会删除[0]和[1],但不会删除[2]。 例如,在此代码中,删除前的数组填充为:。调用后,它有以下条目: 我只想删除13,这样数组就会像这样:
给定一个链表和一个指定的数据值,我想递归地删除包含所述数据的所有节点。(我已经找到了迭代的方法,但我想这样做)。我已将我的结构定义为: 为了删除,我做了这个助手函数,它(应该)返回指向我删除列表的头节点的指针: 然后我想在我的实际列表中使用它: 但这不起作用。看起来我的助手函数实际上不起作用,但我无法理解。出什么事了?
所以我有一个链接列表,我希望能够删除一个数字的第一次出现, 我正在尝试使用递归,但不幸的是,我最终只能删除列表的头部 我有三个不同的类,一个用于末尾的空列表,另一个类声明这个方法和实际的列表。
问题内容: 我目前正在尝试递归删除目录…奇怪的是,我能够找到的最短代码是以下结构,采用了一个 临时内部类 并且采用了 访问者模式 … 资料来源:这里 鉴于新的API消除了太多的混乱和样板,这让人感到非常笨拙和冗长。 有没有更短的方法可以实现强制递归目录删除? 我正在寻找纯本地Java 1.8方法,所以请不要链接到外部库… 问题答案: 您可以结合使用NIO 2和Stream API。 -返回以下所有
我在深度优先搜索算法实现的递归方法方面遇到了一些麻烦。这是二叉树照片: 该方法在树的右侧(55、89、144)工作得很好,但是当它来到左侧时,它返回nil,即使它输入“是”。那么,代码有什么问题呢?节点是Node类的一个实例,它具有值(整数)并链接到左右子级(Node类的其他实例),如果它没有来自该侧的子级,则为nil。 下面是方法代码:
嘿,我一直在研究BFS/DFS,我注意到它们中的许多都有一个轻微的修改,即当一个节点添加到访问集时。 在某种程度上,算法将从堆栈/队列中弹出节点,然后将其添加到访问集。然后它会添加所有没有被访问过的邻居 在另一个实现中,节点不会添加到访问集。相反,它会将所有未访问的邻居添加到堆栈/队列中,但会在将这些邻居添加到堆栈/队列时将其添加到已访问集中。 总之,在一种方法中,当它们弹出到堆栈/队列时,它们被