这是一个功课,我很难想到它。请给我一些关于递归和DP解决方案的想法。非常感谢
生成并打印所有结构上不同的完整二进制文件 n叶的树叶以虚线括号形式, “full”表示所有内部(非叶子)节点都有 正是两个孩子。
例如,有5个不同的完整二叉树 每片有4片叶子。
答案 0 :(得分:3)
在Python中你可以做到这一点
def gendistinct(n):
leafnode = '(.)'
dp = []
newset = set()
newset.add(leafnode)
dp.append(newset)
for i in range(1,n):
newset = set()
for j in range(i):
for leftchild in dp[j]:
for rightchild in dp[i-j-1]:
newset.add('(' + '.' + leftchild + rightchild + ')')
dp.append(newset)
return dp[-1]
alltrees = gendistinct(4)
for tree in alltrees:
print tree
答案 1 :(得分:2)
另一个使用不同策略的Python示例。
这是递归的并且使用生成器。它比其他实现慢,但应该使用更少的内存,因为一次只有一个列表存在于内存中。
#!/usr/bin/env python
import itertools
def all_possible_trees(n):
if n == 1:
yield 'l'
for split in range(1, n):
gen_left = all_possible_trees(split)
gen_right = all_possible_trees(n-split)
for left, right in itertools.product(gen_left, gen_right):
yield [left, right]
if __name__ == '__main__':
import sys
n = int(sys.argv[1])
for thing in all_possible_trees(n):
print(thing)
答案 2 :(得分:1)
我没有看到使用递归的明显方法,但毫无疑问有一个。
相反,我会尝试动态编程方法。
请注意,在完整树的定义下,具有n个叶子的树具有n-1个内部节点。另请注意,树木可以通过在根部连接在一起生成树木,树木的左边是1到n-1个叶子,右边是n-1到1个叶子。
另请注意,各种大小的“树”可以存储为虚线括号字符串。要从这些构建一个新树,连接(左,右)。
首先从带有1个叶子的单个树开始(即单个节点)。构建大小增加到n的树的列表。为了构建k叶树的列表,对于每个j = 1到k-1,对于每个j叶子树,对于每个kj叶子树,连接以构建树(具有k个叶子)并添加到列表中。
在构建n叶树时,可以将它们打印出来而不是存储它们。
有5 * 1 + 2 * 1 + 1 * 2 + 1 * 5 = 14棵树,5片叶子。
有14 * 1 + 5 * 1 + 2 * 2 + 1 * 5 + 1 * 14 = 42棵树,有6片叶子。
答案 3 :(得分:0)
你可以使用递归,在第i步你考虑第i级树,你根据约束选择在这个级别上存在哪些节点: - 上一级有父母 - 没有单身儿童在场(根据您对“完整”树的定义)
当你有N个节点时,递归结束。